From 4c0406c03a48eb73dc6128fb31937570a46235f4 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Thu, 18 Oct 2018 20:18:08 +0200 Subject: [PATCH 01/10] Add TaskBuilder.fs dependency and start preparing code --- TickSpec/Feature.fs | 2 +- TickSpec/ScenarioRun.fs | 54 +++++++----- TickSpec/paket.references | 3 +- paket.dependencies | 1 + paket.lock | 171 ++++++++++++++++++++------------------ 5 files changed, 123 insertions(+), 108 deletions(-) diff --git a/TickSpec/Feature.fs b/TickSpec/Feature.fs index 39efbcf..1d067c5 100644 --- a/TickSpec/Feature.fs +++ b/TickSpec/Feature.fs @@ -3,7 +3,7 @@ open System /// Action type -type Action = delegate of unit -> unit +type Action = delegate of unit -> Task /// Encapsulates Gherkin feature type Feature = { diff --git a/TickSpec/ScenarioRun.fs b/TickSpec/ScenarioRun.fs index 180c8cf..fc87fe8 100644 --- a/TickSpec/ScenarioRun.fs +++ b/TickSpec/ScenarioRun.fs @@ -4,6 +4,8 @@ open System open System.Collections.Generic open System.Reflection open Microsoft.FSharp.Reflection +open FSharp.Control.Tasks.ContextInsensitive +open System.Threading.Tasks /// Splits CSV let split (s:string) = @@ -158,29 +160,35 @@ let invokeStep /// Generate scenario execution function let generate events parsers (scenario, lines) (serviceProviderFactory: unit -> IInstanceProvider) = fun () -> - /// Type instance provider - let provider = serviceProviderFactory() + task { + /// Type instance provider + let provider = serviceProviderFactory() - try - let beforeScenarioEvents, afterScenarioEvents, beforeStepEvents, afterStepEvents = events - /// Invokes events - let invokeEvents events = - events |> Seq.iter (fun (mi:MethodInfo) -> - invoke provider mi [||] - ) try - beforeScenarioEvents |> invokeEvents - // Iterate scenario lines - lines |> Seq.iter (fun (line:LineSource,m,args) -> - try - beforeStepEvents |> invokeEvents - (m,args,line.Bullets,line.Table,line.Doc) |> invokeStep parsers provider - finally - afterStepEvents |> invokeEvents - ) + let beforeScenarioEvents, afterScenarioEvents, beforeStepEvents, afterStepEvents = events + /// Invokes events + let invokeEvents events = + task { + events |> Seq.iter (fun (mi:MethodInfo) -> + task { + do! invoke provider mi [||] + } + ) + } + try + beforeScenarioEvents |> invokeEvents + // Iterate scenario lines + lines |> Seq.iter (fun (line:LineSource,m,args) -> + try + beforeStepEvents |> invokeEvents + (m,args,line.Bullets,line.Table,line.Doc) |> invokeStep parsers provider + finally + afterStepEvents |> invokeEvents + ) + finally + afterScenarioEvents |> invokeEvents finally - afterScenarioEvents |> invokeEvents - finally - match provider with - | :? IDisposable as d -> d.Dispose() - | _ -> () \ No newline at end of file + match provider with + | :? IDisposable as d -> d.Dispose() + | _ -> () + } \ No newline at end of file diff --git a/TickSpec/paket.references b/TickSpec/paket.references index 3a01785..94d13a0 100644 --- a/TickSpec/paket.references +++ b/TickSpec/paket.references @@ -1 +1,2 @@ -FSharp.Core \ No newline at end of file +FSharp.Core +TaskBuilder.fs \ No newline at end of file diff --git a/paket.dependencies b/paket.dependencies index 83dd249..5ae453d 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -3,6 +3,7 @@ framework: auto-detect source https://api.nuget.org/v3/index.json nuget FSharp.Core +nuget TaskBuilder.fs # Test/assertion frameworks nuget NUnit diff --git a/paket.lock b/paket.lock index 6c19991..979b22c 100644 --- a/paket.lock +++ b/paket.lock @@ -8,20 +8,20 @@ NUGET Chessie (0.6) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.0.1.7-alpha) - restriction: || (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) NETStandard.Library (>= 1.6) - restriction: || (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - dotnet-fake (5.8.5) - clitool: true - Fake.Core.CommandLineParsing (>= 5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Runtime (>= 5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + dotnet-fake (5.9.3) - clitool: true + Fake.Core.CommandLineParsing (>= 5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Runtime (>= 5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.5.2) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Microsoft.NETCore.App (>= 2.0) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Mono.Cecil (>= 0.10.1) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Paket.Core (>= 5.181.1) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Core.CommandLineParsing (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.CommandLineParsing (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FParsec (>= 1.0.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - Fake.Core.Context (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.Context (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - Fake.Runtime (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Core.Context (>= 5.8.5) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) + Fake.Runtime (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.Context (>= 5.9.3) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Compiler.Service (>= 25.0.1) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) Microsoft.DotNet.PlatformAbstractions (>= 2.1) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) @@ -547,6 +547,7 @@ NUGET System.Threading.ThreadPool (4.3) - restriction: || (&& (== net45) (>= netcoreapp1.0)) (&& (== net452) (>= netcoreapp1.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp1.0)) System.Runtime (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Runtime.Handles (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) + System.ValueTuple (4.5) System.Xml.ReaderWriter (4.3.1) - restriction: || (&& (== net45) (>= netcoreapp1.0)) (&& (== net452) (>= netcoreapp1.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp1.0)) System.Collections (>= 4.3) - restriction: || (&& (== net45) (>= dnxcore50)) (&& (== net452) (>= dnxcore50)) (&& (== net452) (< net45) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Diagnostics.Debug (>= 4.3) - restriction: || (&& (== net45) (>= dnxcore50)) (&& (== net452) (>= dnxcore50)) (&& (== net452) (< net45) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) @@ -626,6 +627,10 @@ NUGET System.Xml.ReaderWriter (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Xml.XmlDocument (>= 4.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Xml.XPath (>= 4.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) + TaskBuilder.fs (2.1) + FSharp.Core (>= 4.1.17) + NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net452) (< net45) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) + System.ValueTuple (>= 4.4) Unquote (4.0) FSharp.Core (>= 4.2.3) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) xunit (2.4) @@ -659,113 +664,113 @@ NUGET Chessie (0.6) FSharp.Core (>= 4.0.1.7-alpha) NETStandard.Library (>= 1.6) - Fake.Api.GitHub (5.8.5) + Fake.Api.GitHub (5.9.3) FSharp.Core (>= 4.3.4) Octokit (>= 0.32) - Fake.Core.CommandLineParsing (5.8.5) + Fake.Core.CommandLineParsing (5.9.3) FParsec (>= 1.0.3) FSharp.Core (>= 4.3.4) - Fake.Core.Context (5.8.5) + Fake.Core.Context (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Environment (5.8.5) + Fake.Core.Environment (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.FakeVar (5.8.5) - Fake.Core.Context (>= 5.8.5) + Fake.Core.FakeVar (5.9.3) + Fake.Core.Context (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Process (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Core.Process (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Diagnostics.Process (>= 4.3) - Fake.Core.ReleaseNotes (5.8.5) - Fake.Core.SemVer (>= 5.8.5) - Fake.Core.String (>= 5.8.5) + Fake.Core.ReleaseNotes (5.9.3) + Fake.Core.SemVer (>= 5.9.3) + Fake.Core.String (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.SemVer (5.8.5) + Fake.Core.SemVer (5.9.3) FSharp.Core (>= 4.3.4) System.Runtime.Numerics (>= 4.3) - Fake.Core.String (5.8.5) + Fake.Core.String (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Target (5.8.5) - Fake.Core.CommandLineParsing (>= 5.8.5) - Fake.Core.Context (>= 5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) + Fake.Core.Target (5.9.3) + Fake.Core.CommandLineParsing (>= 5.9.3) + Fake.Core.Context (>= 5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) FSharp.Control.Reactive (>= 4.1) FSharp.Core (>= 4.3.4) - System.Reactive.Compatibility (>= 4.1.1) - Fake.Core.Trace (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) + System.Reactive.Compatibility (>= 4.1.2) + Fake.Core.Trace (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.AssemblyInfoFile (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.AssemblyInfoFile (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.Cli (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.DotNet.MSBuild (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.Cli (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.DotNet.MSBuild (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) Newtonsoft.Json (>= 11.0.2) - Fake.DotNet.MSBuild (5.8.5) + Fake.DotNet.MSBuild (5.9.3) BlackFox.VsWhere (>= 0.3.1) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) MSBuild.StructuredLogger (>= 2.0.11) - Fake.DotNet.Paket (5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.Paket (5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.Testing.NUnit (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) - Fake.Testing.Common (>= 5.8.5) + Fake.DotNet.Testing.NUnit (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) + Fake.Testing.Common (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Linq.Parallel (>= 4.3) System.Xml.XDocument (>= 4.3) - Fake.DotNet.Testing.XUnit2 (5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) - Fake.Testing.Common (>= 5.8.5) + Fake.DotNet.Testing.XUnit2 (5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) + Fake.Testing.Common (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.IO.FileSystem (5.8.5) - Fake.Core.String (>= 5.8.5) + Fake.IO.FileSystem (5.9.3) + Fake.Core.String (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Diagnostics.FileVersionInfo (>= 4.3) System.IO.FileSystem.Watcher (>= 4.3) - Fake.Testing.Common (5.8.5) - Fake.Core.Trace (>= 5.8.5) + Fake.Testing.Common (5.9.3) + Fake.Core.Trace (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Tools.Git (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.SemVer (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Tools.Git (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.SemVer (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) FParsec (1.0.3) FSharp.Core (>= 4.2.3) From 24093266ff26ec3d5e518ea14a745a46b5721e71 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Fri, 19 Oct 2018 08:40:51 +0200 Subject: [PATCH 02/10] async prep work --- .../FunctionalInjection/StockSteps.fs | 16 ++++++--- .../FunctionalInjection/paket.references | 3 +- .../NUnit/FSharp.NUnit/StockSteps.fs | 7 +++- .../NUnit/FSharp.NUnit/paket.references | 3 +- TickSpec/Feature.fs | 2 +- TickSpec/ScenarioRun.fs | 34 +++++++++++++++---- 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/Examples/ByFeature/FunctionalInjection/StockSteps.fs b/Examples/ByFeature/FunctionalInjection/StockSteps.fs index 8d0c5e7..e200073 100644 --- a/Examples/ByFeature/FunctionalInjection/StockSteps.fs +++ b/Examples/ByFeature/FunctionalInjection/StockSteps.fs @@ -3,14 +3,22 @@ open NUnit.Framework open Retail open TickSpec +open FSharp.Control.Tasks.ContextInsensitive +open System.Threading.Tasks let [] ``a customer buys a black jumper`` () = () -let [] ``I have (.*) black jumpers left in stock`` (n:int) = - { Count = n } +let [] ``I have (.*) black jumpers left in stock`` (n:int) = + task { + do! Task.Delay 3000 + return { Count = n } + } -let [] ``he returns the jumper for a refund`` (stockItem:StockItem) = - { stockItem with Count = stockItem.Count + 1 } +let [] ``he returns the jumper for a refund`` (stockItem:StockItem) = + async { + do! Async.Sleep 1000 + return { stockItem with Count = stockItem.Count + 1 } + } let [] ``I should have (.*) black jumpers in stock`` (n:int) (stockItem:StockItem) = let passed = (stockItem.Count = n) diff --git a/Examples/ByFeature/FunctionalInjection/paket.references b/Examples/ByFeature/FunctionalInjection/paket.references index 633d784..e197eb9 100644 --- a/Examples/ByFeature/FunctionalInjection/paket.references +++ b/Examples/ByFeature/FunctionalInjection/paket.references @@ -1,4 +1,5 @@ FSharp.Core NUnit Microsoft.NET.Test.Sdk -NUnit3TestAdapter \ No newline at end of file +NUnit3TestAdapter +TaskBuilder.fs \ No newline at end of file diff --git a/Examples/ByFramework/NUnit/FSharp.NUnit/StockSteps.fs b/Examples/ByFramework/NUnit/FSharp.NUnit/StockSteps.fs index b0f7865..ff623ae 100644 --- a/Examples/ByFramework/NUnit/FSharp.NUnit/StockSteps.fs +++ b/Examples/ByFramework/NUnit/FSharp.NUnit/StockSteps.fs @@ -3,10 +3,15 @@ open NUnit.Framework open Retail open TickSpec +open FSharp.Control.Tasks.ContextInsensitive +open System.Threading.Tasks let mutable stockItem = { Count = 0 } -let [] ``a customer buys a black jumper`` () = () +let [] ``a customer buys a black jumper`` () = + task { + do! Task.Delay 1000 + } let [] ``I have (.*) black jumpers left in stock`` (n:int) = stockItem <- { stockItem with Count = n } diff --git a/Examples/ByFramework/NUnit/FSharp.NUnit/paket.references b/Examples/ByFramework/NUnit/FSharp.NUnit/paket.references index 633d784..e197eb9 100644 --- a/Examples/ByFramework/NUnit/FSharp.NUnit/paket.references +++ b/Examples/ByFramework/NUnit/FSharp.NUnit/paket.references @@ -1,4 +1,5 @@ FSharp.Core NUnit Microsoft.NET.Test.Sdk -NUnit3TestAdapter \ No newline at end of file +NUnit3TestAdapter +TaskBuilder.fs \ No newline at end of file diff --git a/TickSpec/Feature.fs b/TickSpec/Feature.fs index 1d067c5..39efbcf 100644 --- a/TickSpec/Feature.fs +++ b/TickSpec/Feature.fs @@ -3,7 +3,7 @@ open System /// Action type -type Action = delegate of unit -> Task +type Action = delegate of unit -> unit /// Encapsulates Gherkin feature type Feature = { diff --git a/TickSpec/ScenarioRun.fs b/TickSpec/ScenarioRun.fs index 36f46ac..e7d212f 100644 --- a/TickSpec/ScenarioRun.fs +++ b/TickSpec/ScenarioRun.fs @@ -4,7 +4,6 @@ open System open System.Collections.Generic open System.Reflection open Microsoft.FSharp.Reflection -open FSharp.Control.Tasks.ContextInsensitive open System.Threading.Tasks /// Splits CSV @@ -18,18 +17,41 @@ let getInstance (provider:IInstanceProvider) (m:MethodInfo) = if m.IsStatic then null else provider.GetService m.DeclaringType +let doCall<'T> (validator: obj, value: obj): bool = + let validatorU: 'T -> bool = unbox validator + let valueU: 'T = unbox value + validatorU valueU + /// Invokes specified method with specified parameters let invoke (provider:IInstanceProvider) (m:MethodInfo) ps = let instance = getInstance provider m - let ret = m.Invoke(instance,ps) - if m.ReturnType <> typeof then - if FSharpType.IsTuple m.ReturnType then - let types = FSharpType.GetTupleElements m.ReturnType + let retP = m.Invoke(instance,ps) + let ret = + + match retP with + | :? Async<_> as a -> + async { + return! a + } |> Async.RunSynchronously :> obj + | :? Task as t -> + async { + do! t |> Async.AwaitTask + } |> Async.RunSynchronously + let tup = retP.GetType() + let p = tup.GetProperty("Result") + if isNull p then (() :> obj) + else p.GetValue(retP) + | _ -> + retP + let typ = if ret = null then typeof else ret.GetType() + if typ <> typeof then + if FSharpType.IsTuple typ then + let types = FSharpType.GetTupleElements typ let values = FSharpValue.GetTupleFields ret Seq.map2 (fun t v -> t,v) types values |> Seq.iter (fun (t,v) -> provider.RegisterInstance(t, v)) else - provider.RegisterInstance(m.ReturnType, ret) + provider.RegisterInstance(typ, ret) /// Converts generic methods let toConcreteMethod (m:MethodInfo) = From 804eab2240b2865edf23b6badfcff0ac5086f422 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sat, 20 Oct 2018 10:51:23 +0200 Subject: [PATCH 03/10] async support working in runner --- .../FunctionalInjection/StockSteps.fs | 5 +- TickSpec/ScenarioRun.fs | 58 ++++++++++++------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Examples/ByFeature/FunctionalInjection/StockSteps.fs b/Examples/ByFeature/FunctionalInjection/StockSteps.fs index e200073..94037c1 100644 --- a/Examples/ByFeature/FunctionalInjection/StockSteps.fs +++ b/Examples/ByFeature/FunctionalInjection/StockSteps.fs @@ -6,7 +6,10 @@ open TickSpec open FSharp.Control.Tasks.ContextInsensitive open System.Threading.Tasks -let [] ``a customer buys a black jumper`` () = () +let [] ``a customer buys a black jumper`` () = + async { + () + } let [] ``I have (.*) black jumpers left in stock`` (n:int) = task { diff --git a/TickSpec/ScenarioRun.fs b/TickSpec/ScenarioRun.fs index e7d212f..6088dd6 100644 --- a/TickSpec/ScenarioRun.fs +++ b/TickSpec/ScenarioRun.fs @@ -17,33 +17,51 @@ let getInstance (provider:IInstanceProvider) (m:MethodInfo) = if m.IsStatic then null else provider.GetService m.DeclaringType -let doCall<'T> (validator: obj, value: obj): bool = - let validatorU: 'T -> bool = unbox validator - let valueU: 'T = unbox value - validatorU valueU +type AsyncInvoker private () = + static let CallMethodInfo = + let flags = System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Static + typeof.GetMethod("DoAsyncCall", flags).GetGenericMethodDefinition() + + static member private DoAsyncCall<'T> (input: obj) = + let typedInput: Async<'T> = unbox input + async { + return! typedInput + } |> Async.RunSynchronously + + static member Call (input: obj, typeOfValue: System.Type) = + CallMethodInfo.MakeGenericMethod(typeOfValue).Invoke(null, [|input|]) :?> _ + +type TaskInvoker private () = + static let CallMethodInfo = + let flags = System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Static + typeof.GetMethod("DoCallAsync", flags).GetGenericMethodDefinition() + + static member private DoCallAsync<'T> (input: obj) = + let typedInput: Task<'T> = unbox input + async { + return! typedInput |> Async.AwaitTask + } |> Async.RunSynchronously + + static member Call (input: obj, typeOfValue: System.Type) = + CallMethodInfo.MakeGenericMethod(typeOfValue).Invoke(null, [|input|]) :?> _ /// Invokes specified method with specified parameters let invoke (provider:IInstanceProvider) (m:MethodInfo) ps = let instance = getInstance provider m + let v = m.ReturnType let retP = m.Invoke(instance,ps) - let ret = - - match retP with - | :? Async<_> as a -> - async { - return! a - } |> Async.RunSynchronously :> obj - | :? Task as t -> + let ret, typ = + match v.Namespace, v.Name with + | "System.Threading.Tasks", "Task`1" -> + (TaskInvoker.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) + | "System.Threading.Tasks", "Task" -> async { - do! t |> Async.AwaitTask + do! retP :?> Task |> Async.AwaitTask } |> Async.RunSynchronously - let tup = retP.GetType() - let p = tup.GetProperty("Result") - if isNull p then (() :> obj) - else p.GetValue(retP) - | _ -> - retP - let typ = if ret = null then typeof else ret.GetType() + (() :> obj, typeof) + | "Microsoft.FSharp.Control", "FSharpAsync`1" -> + (AsyncInvoker.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) + | _, _ -> (retP, v) if typ <> typeof then if FSharpType.IsTuple typ then let types = FSharpType.GetTupleElements typ From addd65af94dc7565512b7ea238c7565b00978353 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sun, 21 Oct 2018 18:36:17 +0200 Subject: [PATCH 04/10] Async examples --- .../ByFeature/AsyncSteps/AsyncSteps.fsproj | 19 ++ Examples/ByFeature/AsyncSteps/NunitWiring.fs | 46 +++++ Examples/ByFeature/AsyncSteps/Time.feature | 7 + Examples/ByFeature/AsyncSteps/TimeSteps.fs | 28 +++ Examples/ByFeature/AsyncSteps/Web.feature | 9 + Examples/ByFeature/AsyncSteps/WebSteps.fs | 33 ++++ .../ByFeature/AsyncSteps/paket.references | 5 + TickSpec.sln | 7 + paket.dependencies | 1 + paket.lock | 173 +++++++++--------- 10 files changed, 244 insertions(+), 84 deletions(-) create mode 100644 Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj create mode 100644 Examples/ByFeature/AsyncSteps/NunitWiring.fs create mode 100644 Examples/ByFeature/AsyncSteps/Time.feature create mode 100644 Examples/ByFeature/AsyncSteps/TimeSteps.fs create mode 100644 Examples/ByFeature/AsyncSteps/Web.feature create mode 100644 Examples/ByFeature/AsyncSteps/WebSteps.fs create mode 100644 Examples/ByFeature/AsyncSteps/paket.references diff --git a/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj b/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj new file mode 100644 index 0000000..8780532 --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.1;net45 + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/ByFeature/AsyncSteps/NunitWiring.fs b/Examples/ByFeature/AsyncSteps/NunitWiring.fs new file mode 100644 index 0000000..13e420e --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/NunitWiring.fs @@ -0,0 +1,46 @@ +module NUnit.TickSpec + +open TickSpec +open NUnit.Framework + +open System.Reflection +open System.Runtime.ExceptionServices + +/// Class containing all BDD tests in current assembly as NUnit unit tests +[] +type FeatureFixture () = + /// Test method for all BDD tests in current assembly as NUnit unit tests + [] + [] + member __.Bdd (scenario:Scenario) = + if scenario.Tags |> Seq.exists ((=) "ignore") then + raise (new IgnoreException("Ignored: " + scenario.ToString())) + try + scenario.Action.Invoke() + with + | :? TargetInvocationException as ex -> ExceptionDispatchInfo.Capture(ex.InnerException).Throw() + + /// All test scenarios from feature files in current assembly + static member Scenarios = + let createFeatureData (feature:Feature) = + let createTestCaseData (feature:Feature) (scenario:Scenario) = + let enhanceScenarioName parameters scenarioName = + let replaceParameterInScenarioName (scenarioName:string) parameter = + scenarioName.Replace("<" + fst parameter + ">", snd parameter) + parameters + |> Seq.fold replaceParameterInScenarioName scenarioName + (new TestCaseData(scenario)) + .SetName(enhanceScenarioName scenario.Parameters scenario.Name) + .SetProperty("Feature", feature.Name.Substring(9)) + |> Seq.foldBack (fun (tag:string) data -> data.SetProperty("Tag", tag)) scenario.Tags + feature.Scenarios + |> Seq.map (createTestCaseData feature) + + let assembly = Assembly.GetExecutingAssembly() + let definitions = new StepDefinitions(assembly.GetTypes()) + + assembly.GetManifestResourceNames() + |> Seq.filter (fun (n:string) -> n.EndsWith(".feature") ) + |> Seq.collect (fun n -> + definitions.GenerateFeature(n, assembly.GetManifestResourceStream(n)) + |> createFeatureData) \ No newline at end of file diff --git a/Examples/ByFeature/AsyncSteps/Time.feature b/Examples/ByFeature/AsyncSteps/Time.feature new file mode 100644 index 0000000..13c2048 --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/Time.feature @@ -0,0 +1,7 @@ +Feature: Time + +Scenario: Time + Given having current time + When I sleep for 20ms using Async + And I sleep for 20ms using Tasks + Then the current time is at least 40ms higher than it was diff --git a/Examples/ByFeature/AsyncSteps/TimeSteps.fs b/Examples/ByFeature/AsyncSteps/TimeSteps.fs new file mode 100644 index 0000000..60a80aa --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/TimeSteps.fs @@ -0,0 +1,28 @@ +module TimeSteps + +open NUnit.Framework +open TickSpec +open System.Net +open System +open FSharp.Control.Tasks.V2.ContextInsensitive +open System.Threading.Tasks + +type Time = + | Time of DateTime + +let [] ``having current time`` () = + Time DateTime.Now + +let [] ``I sleep for (\d*)ms using Async`` (duration: int) = + async { + do! Async.Sleep duration + } + +let [] ``I sleep for (\d*)ms using Tasks`` (duration: int) = + task { + do! Task.Delay duration + } + +let [] ``the current time is at least (\d*)ms higher than it was`` (duration: int) (Time previousCurrentTime) = + int (DateTime.Now - previousCurrentTime).TotalMilliseconds >= duration + |> Assert.True \ No newline at end of file diff --git a/Examples/ByFeature/AsyncSteps/Web.feature b/Examples/ByFeature/AsyncSteps/Web.feature new file mode 100644 index 0000000..ff24ff3 --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/Web.feature @@ -0,0 +1,9 @@ +Feature: Web requests + +Scenario: Google contains Google + When I download https://www.google.com/ web page using Async + Then the downloaded page contains "Google" + +Scenario: Bing contains Bing + When I download https://www.bing.com/ web page using Tasks + Then the downloaded page contains "Bing" \ No newline at end of file diff --git a/Examples/ByFeature/AsyncSteps/WebSteps.fs b/Examples/ByFeature/AsyncSteps/WebSteps.fs new file mode 100644 index 0000000..6e2a687 --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/WebSteps.fs @@ -0,0 +1,33 @@ +module WebSteps + +open NUnit.Framework +open TickSpec +open System.Net +open System +open FSharp.Control.Tasks.V2.ContextInsensitive + +type DownloadedPage = + | DownloadedPage of string + +let [] ``I download (.*) web page using Async`` address = + async { + let req = WebRequest.Create(Uri address) + use! resp = req.AsyncGetResponse() + use stream = resp.GetResponseStream() + use reader = new IO.StreamReader(stream) + return reader.ReadToEnd() |> DownloadedPage + } + +let [] ``I download (.*) web page using Tasks`` address = + task { + let req = WebRequest.Create(Uri address) + use! resp = req.GetResponseAsync() + use stream = resp.GetResponseStream() + use reader = new IO.StreamReader(stream) + return reader.ReadToEnd() |> DownloadedPage + } + +let [] ``the downloaded page contains "(.*)"`` (text: string) (DownloadedPage page) = + page.Contains(text) + |> Assert.True + diff --git a/Examples/ByFeature/AsyncSteps/paket.references b/Examples/ByFeature/AsyncSteps/paket.references new file mode 100644 index 0000000..e197eb9 --- /dev/null +++ b/Examples/ByFeature/AsyncSteps/paket.references @@ -0,0 +1,5 @@ +FSharp.Core +NUnit +Microsoft.NET.Test.Sdk +NUnit3TestAdapter +TaskBuilder.fs \ No newline at end of file diff --git a/TickSpec.sln b/TickSpec.sln index a9f0301..3d7e3c6 100644 --- a/TickSpec.sln +++ b/TickSpec.sln @@ -62,6 +62,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "DependencyInjection", "Exam EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FunctionalInjection", "Examples\ByFeature\FunctionalInjection\FunctionalInjection.fsproj", "{1CE6B475-C94F-438E-97D4-5E99FD0F04D4}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "AsyncSteps", "Examples\ByFeature\AsyncSteps\AsyncSteps.fsproj", "{B1CD5BF8-4A92-4005-909F-BCBFDE35D150}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -120,6 +122,10 @@ Global {1CE6B475-C94F-438E-97D4-5E99FD0F04D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {1CE6B475-C94F-438E-97D4-5E99FD0F04D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {1CE6B475-C94F-438E-97D4-5E99FD0F04D4}.Release|Any CPU.Build.0 = Release|Any CPU + {B1CD5BF8-4A92-4005-909F-BCBFDE35D150}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1CD5BF8-4A92-4005-909F-BCBFDE35D150}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1CD5BF8-4A92-4005-909F-BCBFDE35D150}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1CD5BF8-4A92-4005-909F-BCBFDE35D150}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -143,6 +149,7 @@ Global {4F45F8E2-F9FD-4C80-B4E0-A38B17A791D2} = {EB1F6262-0913-4464-A034-4F4D01268E83} {6DD7F109-6798-4CAF-BD13-7BA4689BD892} = {EB1F6262-0913-4464-A034-4F4D01268E83} {1CE6B475-C94F-438E-97D4-5E99FD0F04D4} = {EB1F6262-0913-4464-A034-4F4D01268E83} + {B1CD5BF8-4A92-4005-909F-BCBFDE35D150} = {EB1F6262-0913-4464-A034-4F4D01268E83} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8B381617-F1EE-4BFC-8EAE-CAB4DBB4B9A2} diff --git a/paket.dependencies b/paket.dependencies index 83dd249..1721a53 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -11,6 +11,7 @@ nuget Microsoft.NET.Test.Sdk nuget xunit ~> 2 # there are v1 examples but most integrations use v2 nuget xunit.runner.visualstudio ~> 2 version_in_path: false nuget Unquote +nuget TaskBuilder.fs # Example container to illustrate integration nuget Autofac diff --git a/paket.lock b/paket.lock index 6c19991..541ae50 100644 --- a/paket.lock +++ b/paket.lock @@ -8,20 +8,20 @@ NUGET Chessie (0.6) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.0.1.7-alpha) - restriction: || (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) NETStandard.Library (>= 1.6) - restriction: || (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - dotnet-fake (5.8.5) - clitool: true - Fake.Core.CommandLineParsing (>= 5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Runtime (>= 5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + dotnet-fake (5.9.3) - clitool: true + Fake.Core.CommandLineParsing (>= 5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Runtime (>= 5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.5.2) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Microsoft.NETCore.App (>= 2.0) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Mono.Cecil (>= 0.10.1) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) Paket.Core (>= 5.181.1) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Core.CommandLineParsing (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.CommandLineParsing (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FParsec (>= 1.0.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - Fake.Core.Context (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.Context (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.6)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) - Fake.Runtime (5.8.5) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) - Fake.Core.Context (>= 5.8.5) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) + Fake.Runtime (5.9.3) - restriction: || (&& (== net45) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.0)) + Fake.Core.Context (>= 5.9.3) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Compiler.Service (>= 25.0.1) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) FSharp.Core (>= 4.3.4) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) Microsoft.DotNet.PlatformAbstractions (>= 2.1) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) @@ -547,6 +547,7 @@ NUGET System.Threading.ThreadPool (4.3) - restriction: || (&& (== net45) (>= netcoreapp1.0)) (&& (== net452) (>= netcoreapp1.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp1.0)) System.Runtime (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Runtime.Handles (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) + System.ValueTuple (4.5) System.Xml.ReaderWriter (4.3.1) - restriction: || (&& (== net45) (>= netcoreapp1.0)) (&& (== net452) (>= netcoreapp1.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp1.0)) System.Collections (>= 4.3) - restriction: || (&& (== net45) (>= dnxcore50)) (&& (== net452) (>= dnxcore50)) (&& (== net452) (< net45) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Diagnostics.Debug (>= 4.3) - restriction: || (&& (== net45) (>= dnxcore50)) (&& (== net452) (>= dnxcore50)) (&& (== net452) (< net45) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) @@ -626,6 +627,10 @@ NUGET System.Xml.ReaderWriter (>= 4.3) - restriction: || (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Xml.XmlDocument (>= 4.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) System.Xml.XPath (>= 4.3) - restriction: || (&& (== net45) (>= net46)) (&& (== net45) (>= netstandard1.3)) (&& (== net452) (>= net46)) (&& (== net452) (>= netstandard1.3)) (== netcoreapp2.1) (== netstandard2.0) + TaskBuilder.fs (2.1) + FSharp.Core (>= 4.1.17) + NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net452) (< net45) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) + System.ValueTuple (>= 4.4) Unquote (4.0) FSharp.Core (>= 4.2.3) - restriction: || (&& (== net45) (>= netstandard2.0)) (&& (== net452) (>= netstandard2.0)) (== netcoreapp2.1) (== netstandard2.0) xunit (2.4) @@ -654,118 +659,118 @@ STORAGE: NONE RESTRICTION: == netstandard2.0 NUGET remote: https://api.nuget.org/v3/index.json - BlackFox.VsWhere (0.3.1) + BlackFox.VsWhere (0.3.2) FSharp.Core (>= 4.2.3) Chessie (0.6) FSharp.Core (>= 4.0.1.7-alpha) NETStandard.Library (>= 1.6) - Fake.Api.GitHub (5.8.5) + Fake.Api.GitHub (5.9.3) FSharp.Core (>= 4.3.4) Octokit (>= 0.32) - Fake.Core.CommandLineParsing (5.8.5) + Fake.Core.CommandLineParsing (5.9.3) FParsec (>= 1.0.3) FSharp.Core (>= 4.3.4) - Fake.Core.Context (5.8.5) + Fake.Core.Context (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Environment (5.8.5) + Fake.Core.Environment (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.FakeVar (5.8.5) - Fake.Core.Context (>= 5.8.5) + Fake.Core.FakeVar (5.9.3) + Fake.Core.Context (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Process (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Core.Process (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Diagnostics.Process (>= 4.3) - Fake.Core.ReleaseNotes (5.8.5) - Fake.Core.SemVer (>= 5.8.5) - Fake.Core.String (>= 5.8.5) + Fake.Core.ReleaseNotes (5.9.3) + Fake.Core.SemVer (>= 5.9.3) + Fake.Core.String (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.SemVer (5.8.5) + Fake.Core.SemVer (5.9.3) FSharp.Core (>= 4.3.4) System.Runtime.Numerics (>= 4.3) - Fake.Core.String (5.8.5) + Fake.Core.String (5.9.3) FSharp.Core (>= 4.3.4) - Fake.Core.Target (5.8.5) - Fake.Core.CommandLineParsing (>= 5.8.5) - Fake.Core.Context (>= 5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) + Fake.Core.Target (5.9.3) + Fake.Core.CommandLineParsing (>= 5.9.3) + Fake.Core.Context (>= 5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) FSharp.Control.Reactive (>= 4.1) FSharp.Core (>= 4.3.4) - System.Reactive.Compatibility (>= 4.1.1) - Fake.Core.Trace (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.FakeVar (>= 5.8.5) + System.Reactive.Compatibility (>= 4.1.2) + Fake.Core.Trace (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.FakeVar (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.AssemblyInfoFile (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.AssemblyInfoFile (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.Cli (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.DotNet.MSBuild (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.Cli (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.DotNet.MSBuild (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) Newtonsoft.Json (>= 11.0.2) - Fake.DotNet.MSBuild (5.8.5) + Fake.DotNet.MSBuild (5.9.3) BlackFox.VsWhere (>= 0.3.1) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) MSBuild.StructuredLogger (>= 2.0.11) - Fake.DotNet.Paket (5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.DotNet.Paket (5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.DotNet.Testing.NUnit (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) - Fake.Testing.Common (>= 5.8.5) + Fake.DotNet.Testing.NUnit (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) + Fake.Testing.Common (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Linq.Parallel (>= 4.3) System.Xml.XDocument (>= 4.3) - Fake.DotNet.Testing.XUnit2 (5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) - Fake.Testing.Common (>= 5.8.5) + Fake.DotNet.Testing.XUnit2 (5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) + Fake.Testing.Common (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.IO.FileSystem (5.8.5) - Fake.Core.String (>= 5.8.5) + Fake.IO.FileSystem (5.9.3) + Fake.Core.String (>= 5.9.3) FSharp.Core (>= 4.3.4) System.Diagnostics.FileVersionInfo (>= 4.3) System.IO.FileSystem.Watcher (>= 4.3) - Fake.Testing.Common (5.8.5) - Fake.Core.Trace (>= 5.8.5) + Fake.Testing.Common (5.9.3) + Fake.Core.Trace (>= 5.9.3) FSharp.Core (>= 4.3.4) - Fake.Tools.Git (5.8.5) - Fake.Core.Environment (>= 5.8.5) - Fake.Core.Process (>= 5.8.5) - Fake.Core.SemVer (>= 5.8.5) - Fake.Core.String (>= 5.8.5) - Fake.Core.Trace (>= 5.8.5) - Fake.IO.FileSystem (>= 5.8.5) + Fake.Tools.Git (5.9.3) + Fake.Core.Environment (>= 5.9.3) + Fake.Core.Process (>= 5.9.3) + Fake.Core.SemVer (>= 5.9.3) + Fake.Core.String (>= 5.9.3) + Fake.Core.Trace (>= 5.9.3) + Fake.IO.FileSystem (>= 5.9.3) FSharp.Core (>= 4.3.4) FParsec (1.0.3) FSharp.Core (>= 4.2.3) From df208da893425c52188fa807dc7ab377720ae168 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sun, 21 Oct 2018 21:57:44 +0200 Subject: [PATCH 05/10] Support for async in generated code --- Examples/ByFeature/AsyncSteps/TimeSteps.fs | 1 - TickSpec/AsyncInvoker.fs | 18 +++++++++++++ TickSpec/ScenarioGen.fs | 30 ++++++++++++++++++---- TickSpec/TickSpec.fsproj | 1 + 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 TickSpec/AsyncInvoker.fs diff --git a/Examples/ByFeature/AsyncSteps/TimeSteps.fs b/Examples/ByFeature/AsyncSteps/TimeSteps.fs index 60a80aa..fbfa888 100644 --- a/Examples/ByFeature/AsyncSteps/TimeSteps.fs +++ b/Examples/ByFeature/AsyncSteps/TimeSteps.fs @@ -2,7 +2,6 @@ open NUnit.Framework open TickSpec -open System.Net open System open FSharp.Control.Tasks.V2.ContextInsensitive open System.Threading.Tasks diff --git a/TickSpec/AsyncInvoker.fs b/TickSpec/AsyncInvoker.fs new file mode 100644 index 0000000..3c999f1 --- /dev/null +++ b/TickSpec/AsyncInvoker.fs @@ -0,0 +1,18 @@ +namespace TickSpec +open System.Threading.Tasks + +type AsyncInvoker() = + static member DoTaskCall (task: Task) = + async { + do! task |> Async.AwaitTask + } |> Async.RunSynchronously + + static member DoCallAsync<'T> (input: Task<'T>) = + async { + return! input |> Async.AwaitTask + } |> Async.RunSynchronously + + static member DoAsyncCall<'T> (input: Async<'T>) = + async { + return! input + } |> Async.RunSynchronously \ No newline at end of file diff --git a/TickSpec/ScenarioGen.fs b/TickSpec/ScenarioGen.fs index e4f7e09..133ec87 100644 --- a/TickSpec/ScenarioGen.fs +++ b/TickSpec/ScenarioGen.fs @@ -433,8 +433,28 @@ let defineStepMethod else gen.Emit(OpCodes.Callvirt, mi) - if mi.ReturnType <> typeof then - gen.Emit(OpCodes.Box,mi.ReturnType) + let v = mi.ReturnType + let typ = + match v.Namespace, v.Name with + | "System.Threading.Tasks", "Task`1" -> + let callInfo = + typeof.GetMethod("DoCallAsync", BindingFlags.Public ||| BindingFlags.Static).MakeGenericMethod(v.GenericTypeArguments.[0]) + gen.EmitCall(OpCodes.Call, callInfo, null) + v.GenericTypeArguments.[0] + | "System.Threading.Tasks", "Task" -> + let callInfo = + typeof.GetMethod("DoTaskCall", BindingFlags.Public ||| BindingFlags.Static) + gen.EmitCall(OpCodes.Call, callInfo, null) + typeof + | "Microsoft.FSharp.Control", "FSharpAsync`1" -> + let callInfo = + typeof.GetMethod("DoAsyncCall", BindingFlags.Public ||| BindingFlags.Static).MakeGenericMethod(v.GenericTypeArguments.[0]) + gen.EmitCall(OpCodes.Call, callInfo, null) + v.GenericTypeArguments.[0] + | _, _ -> v + + if typ <> typeof then + gen.Emit(OpCodes.Box,typ) let local0 = gen.DeclareLocal(typeof).LocalIndex gen.Emit(OpCodes.Stloc, local0) @@ -449,8 +469,8 @@ let defineStepMethod gen.Emit(OpCodes.Ldloc, l) gen.Emit(OpCodes.Callvirt, typeof.GetMethod("RegisterInstance")) - if FSharpType.IsTuple mi.ReturnType then - let types = FSharpType.GetTupleElements mi.ReturnType + if FSharpType.IsTuple typ then + let types = FSharpType.GetTupleElements typ for i = 0 to (types.Length - 1) do let t = types.[i] let local1 = gen.DeclareLocal(typeof).LocalIndex @@ -462,7 +482,7 @@ let defineStepMethod emitRegisterInstanceCall t local1 else - emitRegisterInstanceCall (mi.ReturnType) local0 + emitRegisterInstanceCall typ local0 // Emit return gen.Emit(OpCodes.Ret) diff --git a/TickSpec/TickSpec.fsproj b/TickSpec/TickSpec.fsproj index c27bd0f..304a46b 100644 --- a/TickSpec/TickSpec.fsproj +++ b/TickSpec/TickSpec.fsproj @@ -19,6 +19,7 @@ + From 605abf706dddf6bf17807d89f7370d78ea38b85d Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sun, 21 Oct 2018 22:03:58 +0200 Subject: [PATCH 06/10] paket update --- paket.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paket.lock b/paket.lock index f232f4b..541ae50 100644 --- a/paket.lock +++ b/paket.lock @@ -80,7 +80,7 @@ NUGET Microsoft.NETCore.DotNetHostResolver (>= 2.1.5) Microsoft.NETCore.DotNetHostResolver (2.1.5) - restriction: || (&& (== net45) (>= netcoreapp2.1)) (&& (== net452) (>= netcoreapp2.1)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp2.1)) Microsoft.NETCore.DotNetAppHost (>= 2.1.5) - Microsoft.NETCore.Platforms (2.1.1) - restriction: || (&& (== net45) (< net20) (>= netstandard2.0)) (&& (== net45) (>= netcoreapp2.0)) (&& (== net45) (>= netcoreapp2.1)) (&& (== net45) (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (== net45) (>= netstandard2.0) (>= uap10.0)) (&& (== net45) (>= netstandard2.0) (>= uap10.1)) (&& (== net45) (>= netstandard2.0) (>= wp8)) (&& (== net45) (>= netstandard2.0) (>= wpa81)) (&& (== net452) (< net20) (>= netstandard2.0)) (&& (== net452) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.1)) (&& (== net452) (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (== net452) (>= netstandard2.0) (>= uap10.0)) (&& (== net452) (>= netstandard2.0) (>= uap10.1)) (&& (== net452) (>= netstandard2.0) (>= wp8)) (&& (== net452) (>= netstandard2.0) (>= wpa81)) (== netcoreapp2.1) (== netstandard2.0) + Microsoft.NETCore.Platforms (2.1.1) - restriction: || (&& (== net45) (< net20) (>= netstandard2.0)) (&& (== net45) (>= netcoreapp2.0)) (&& (== net45) (>= netcoreapp2.1)) (&& (== net45) (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (== net45) (>= netstandard2.0) (>= uap10.0)) (&& (== net45) (>= netstandard2.0) (>= wp8)) (&& (== net45) (>= netstandard2.0) (>= wpa81)) (&& (== net452) (< net20) (>= netstandard2.0)) (&& (== net452) (>= netcoreapp2.0)) (&& (== net452) (>= netcoreapp2.1)) (&& (== net452) (< netstandard1.0) (>= netstandard2.0) (>= win8)) (&& (== net452) (>= netstandard2.0) (>= uap10.0)) (&& (== net452) (>= netstandard2.0) (>= wp8)) (&& (== net452) (>= netstandard2.0) (>= wpa81)) (== netcoreapp2.1) (== netstandard2.0) Microsoft.NETCore.Targets (2.1) - restriction: || (&& (== net45) (>= netcoreapp2.1)) (&& (== net452) (>= dnxcore50)) (&& (== net452) (< net45)) (&& (== net452) (>= netcoreapp2.1)) (== netcoreapp2.1) (== netstandard2.0) Microsoft.TestPlatform.ObjectModel (15.9) - restriction: || (&& (== net45) (>= netcoreapp1.0)) (&& (== net452) (>= netcoreapp1.0)) (== netcoreapp2.1) (&& (== netstandard2.0) (>= netcoreapp1.0)) NETStandard.Library (>= 1.6) - restriction: || (&& (== net45) (>= netstandard1.5)) (&& (== net452) (< net451) (>= netstandard1.5)) (== netcoreapp2.1) (== netstandard2.0) From c36f16407134fe30327bf0682f95589e74f7b82e Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sun, 21 Oct 2018 23:06:25 +0200 Subject: [PATCH 07/10] fix NUnit wiring to be according to new parsing --- Examples/ByFeature/AsyncSteps/NunitWiring.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/ByFeature/AsyncSteps/NunitWiring.fs b/Examples/ByFeature/AsyncSteps/NunitWiring.fs index 13e420e..c9a74f4 100644 --- a/Examples/ByFeature/AsyncSteps/NunitWiring.fs +++ b/Examples/ByFeature/AsyncSteps/NunitWiring.fs @@ -31,7 +31,7 @@ type FeatureFixture () = |> Seq.fold replaceParameterInScenarioName scenarioName (new TestCaseData(scenario)) .SetName(enhanceScenarioName scenario.Parameters scenario.Name) - .SetProperty("Feature", feature.Name.Substring(9)) + .SetProperty("Feature", feature.Name) |> Seq.foldBack (fun (tag:string) data -> data.SetProperty("Tag", tag)) scenario.Tags feature.Scenarios |> Seq.map (createTestCaseData feature) From 81386f7913b6f2ca5ae7893b4881f1032584ce45 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Sun, 21 Oct 2018 23:07:05 +0200 Subject: [PATCH 08/10] Reuse AsyncInvoker in scenario run --- TickSpec/ScenarioRun.fs | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/TickSpec/ScenarioRun.fs b/TickSpec/ScenarioRun.fs index 6088dd6..9b0f426 100644 --- a/TickSpec/ScenarioRun.fs +++ b/TickSpec/ScenarioRun.fs @@ -17,30 +17,26 @@ let getInstance (provider:IInstanceProvider) (m:MethodInfo) = if m.IsStatic then null else provider.GetService m.DeclaringType -type AsyncInvoker private () = +type AsyncHelper private () = static let CallMethodInfo = let flags = System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Static - typeof.GetMethod("DoAsyncCall", flags).GetGenericMethodDefinition() + typeof.GetMethod("DoAsyncCall", flags).GetGenericMethodDefinition() static member private DoAsyncCall<'T> (input: obj) = let typedInput: Async<'T> = unbox input - async { - return! typedInput - } |> Async.RunSynchronously + AsyncInvoker.DoAsyncCall typedInput static member Call (input: obj, typeOfValue: System.Type) = CallMethodInfo.MakeGenericMethod(typeOfValue).Invoke(null, [|input|]) :?> _ -type TaskInvoker private () = +type TaskHelper private () = static let CallMethodInfo = let flags = System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Static - typeof.GetMethod("DoCallAsync", flags).GetGenericMethodDefinition() + typeof.GetMethod("DoCallAsync", flags).GetGenericMethodDefinition() static member private DoCallAsync<'T> (input: obj) = let typedInput: Task<'T> = unbox input - async { - return! typedInput |> Async.AwaitTask - } |> Async.RunSynchronously + AsyncInvoker.DoCallAsync typedInput static member Call (input: obj, typeOfValue: System.Type) = CallMethodInfo.MakeGenericMethod(typeOfValue).Invoke(null, [|input|]) :?> _ @@ -53,14 +49,12 @@ let invoke (provider:IInstanceProvider) (m:MethodInfo) ps = let ret, typ = match v.Namespace, v.Name with | "System.Threading.Tasks", "Task`1" -> - (TaskInvoker.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) + (TaskHelper.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) | "System.Threading.Tasks", "Task" -> - async { - do! retP :?> Task |> Async.AwaitTask - } |> Async.RunSynchronously + AsyncInvoker.DoTaskCall (retP :?> Task) (() :> obj, typeof) | "Microsoft.FSharp.Control", "FSharpAsync`1" -> - (AsyncInvoker.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) + (AsyncHelper.Call(retP, v.GenericTypeArguments.[0]), v.GenericTypeArguments.[0]) | _, _ -> (retP, v) if typ <> typeof then if FSharpType.IsTuple typ then From 087f2009445acc302c28b8994b6eaad62efe84c5 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Fri, 26 Oct 2018 20:24:50 +0200 Subject: [PATCH 09/10] Update Fsharp.Core to support AwaitTask properly --- TickSpec/TickSpec.fsproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TickSpec/TickSpec.fsproj b/TickSpec/TickSpec.fsproj index acd2185..e42f889 100644 --- a/TickSpec/TickSpec.fsproj +++ b/TickSpec/TickSpec.fsproj @@ -40,8 +40,7 @@ - - + all runtime; build; native; contentfiles; analyzers From 1f85e4762413758022052f32db222e46f2158245 Mon Sep 17 00:00:00 2001 From: Michal Kovac Date: Fri, 26 Oct 2018 20:35:23 +0200 Subject: [PATCH 10/10] paket.references removal --- Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj | 1 - Examples/ByFeature/AsyncSteps/paket.references | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 Examples/ByFeature/AsyncSteps/paket.references diff --git a/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj b/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj index 0251c5e..0cb62f2 100644 --- a/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj +++ b/Examples/ByFeature/AsyncSteps/AsyncSteps.fsproj @@ -6,7 +6,6 @@ false - diff --git a/Examples/ByFeature/AsyncSteps/paket.references b/Examples/ByFeature/AsyncSteps/paket.references deleted file mode 100644 index e197eb9..0000000 --- a/Examples/ByFeature/AsyncSteps/paket.references +++ /dev/null @@ -1,5 +0,0 @@ -FSharp.Core -NUnit -Microsoft.NET.Test.Sdk -NUnit3TestAdapter -TaskBuilder.fs \ No newline at end of file