Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
"husky"
],
"rollForward": false
},
"fsdocs-tool": {
"version": "20.0.1",
"commands": [
"fsdocs"
],
"rollForward": false
}
}
}
46 changes: 46 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Docs

# Trigger this Action when new code is pushed to the main branch
on:
push:
branches:
- main

# We need some permissions to publish to Github Pages
permissions:
contents: write
pages: write
id-token: write

jobs:
build:
runs-on: ubuntu-latest
steps:
# Checkout the source code
- uses: actions/checkout@v4
# Setup dotnet, please use a global.json to ensure the right SDK is used!
- name: Setup .NET
uses: actions/setup-dotnet@v3
# Restore the local tools
- name: Restore tools
run: dotnet tool restore
# Build the code for the API documentation
- name: Build code
run: dotnet build -c Release ApiStub.FSharp.sln
# Generate the documentation files
- name: Generate the documentation'
run: dotnet fsdocs build --properties Configuration=Release
# Upload the static files
- name: Upload documentation
uses: actions/upload-pages-artifact@v2
with:
path: ./output

# GitHub Actions recommends deploying in a separate job.
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ jobs:
# Main branch only
if: github.ref == 'refs/heads/main'
run: |
dotnet nuget push **/*.nupkg --api-key ${{secrets.NUGET_KEY}} --skip-duplicate
dotnet nuget push **/*.nupkg --api-key ${{secrets.NUGET_KEY}} --skip-duplicates
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,10 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# FSharp.Formatting
.fsdocs/
output/
tmp/

.DS_Store
2 changes: 1 addition & 1 deletion ApiStub.FSharp/ApiStub.FSharp.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>ApiStub.FSharp</PackageId>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
<Authors>jkone27</Authors>
<RequireLicenseAcceptance>false</RequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
76 changes: 43 additions & 33 deletions ApiStub.FSharp/BDD.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,29 @@ open ApiStub.FSharp.HttpResponseHelpers
module BDD =


/// Defines a BDD scenario
type Scenario<'TStartup when 'TStartup: not struct> =
{ UseCase: string
TestClient: TestClient<'TStartup> }

/// Defines the context propagated through the test
type Environment<'TStartup, 'FeatureStubData when 'TStartup: not struct> =
{ Scenario: Scenario<'TStartup>
FeatureStubData: 'FeatureStubData
Factory: 'TStartup WebApplicationFactory
Client: HttpClient }

/// Result of a Given gherkin clause
type GivenResult<'ArrangeData, 'FeatureStubData, 'TStartup when 'TStartup: not struct> =
{ Environment: Environment<'TStartup, 'FeatureStubData>
ArrangeData: 'ArrangeData } // once preconditions are set

/// Result of a When gherkin clause
type WhenResult<'ArrangeData, 'FeatureStubData, 'AssertData, 'TStartup when 'TStartup: not struct> =
{ Given: GivenResult<'ArrangeData, 'FeatureStubData, 'TStartup>
AssertData: 'AssertData }


/// Generic step type for the BDD steps
type Step<'TStartup, 'FeatureStubData, 'ArrangeData, 'AssertData when 'TStartup: not struct> =
| Scenario of Scenario<'TStartup>
| Environment of Environment<'TStartup, 'FeatureStubData>
Expand All @@ -37,11 +41,13 @@ module BDD =
| Invalid of error: string


/// Scenario builder
let SCENARIO useCase testClient =
{ UseCase = useCase
TestClient = testClient }
|> Step.Scenario

/// Setup the Environment for the given scenario
let SETUP arrangeTestEnvironment customizeClient step =
task {

Expand All @@ -58,6 +64,7 @@ module BDD =
| _ -> return Step.Invalid("only environment is supported for ENVIRONMENT_SETUP")
}

/// specify a GIVEN gherkin clause
let GIVEN setPreconditions stepTask =
task {

Expand Down Expand Up @@ -88,6 +95,7 @@ module BDD =
| Result.Error(e) -> Step.Invalid(e)
}

/// specify a WHEN gherkin clause
let WHEN action stepTask =
task {

Expand All @@ -114,6 +122,7 @@ module BDD =
return r
}

/// Specify an assert in THEN gherkin format
let THEN assertAction stepTask =
task {

Expand All @@ -126,6 +135,7 @@ module BDD =
| _ -> return Step.Invalid($"{step} is not supported in WHEN clause")
}

/// Conclude the pipeline of steps
let END stepTask =
task {

Expand All @@ -141,35 +151,35 @@ module BDD =
}


// [<Fact>] sample
let ``when i call /hello i get 'world' back with 200 ok`` (testClient: TestClient<_>) =

let stubData = [ 1, 2, 3 ]

testClient { GET "/hello" (fun _ _ -> $"hello world {stubData}" |> R_TEXT) }
|> SCENARIO "when i call /hello i get 'world' back with 200 ok"
|> SETUP
(fun s ->
task {

let test = s.TestClient

let f = test.GetFactory()

return
{ Client = f.CreateClient()
Factory = f
Scenario = s
FeatureStubData = stubData }
})
(fun c -> c)
|> GIVEN(fun g -> "hello" |> Task.FromResult)
|> WHEN(fun g ->
task {
let! (r: HttpResponseMessage) = g.Environment.Client.GetAsync("/Hello")
return! r.Content.ReadAsStringAsync()
})
|> THEN(fun w ->
let _ = ("hello world 1,2,3" = w.AssertData)
())
|> END
// [<Fact>] sample
// let ``when i call /hello i get 'world' back with 200 ok`` (testClient: TestClient<_>) =

// let stubData = [ 1, 2, 3 ]

// testClient { GET "/hello" (fun _ _ -> $"hello world {stubData}" |> R_TEXT) }
// |> SCENARIO "when i call /hello i get 'world' back with 200 ok"
// |> SETUP
// (fun s ->
// task {

// let test = s.TestClient

// let f = test.GetFactory()

// return
// { Client = f.CreateClient()
// Factory = f
// Scenario = s
// FeatureStubData = stubData }
// })
// (fun c -> c)
// |> GIVEN(fun g -> "hello" |> Task.FromResult)
// |> WHEN(fun g ->
// task {
// let! (r: HttpResponseMessage) = g.Environment.Client.GetAsync("/Hello")
// return! r.Content.ReadAsStringAsync()
// })
// |> THEN(fun w ->
// let _ = ("hello world 1,2,3" = w.AssertData)
// ())
// |> END
1 change: 1 addition & 0 deletions ApiStub.FSharp/BuilderExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ open System.Threading.Tasks
open System
open Microsoft.AspNetCore.TestHost

/// Utility methods for aspnetcore configuration
module BuilderExtensions =

let configure_services (configure: IServiceCollection -> 'a) (builder: IWebHostBuilder) : IWebHostBuilder =
Expand Down
2 changes: 2 additions & 0 deletions ApiStub.FSharp/CE.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ open Microsoft.Extensions.Http
open Microsoft.AspNetCore.Routing.Template
open Microsoft.AspNetCore.Routing

/// computation expression module (builder CE), contains `TestClient<T>` that wraps `WebApplicationFactory<T>`
module CE =
open BuilderExtensions
open HttpResponseHelpers
Expand All @@ -17,6 +18,7 @@ module CE =
let private toAsync stub =
fun req args -> task { return stub req args }

/// `TestClient<T>` wraps `WebApplicationFactory<T>` and exposes a builder CE with utility to define api client stubs and other features
type TestClient<'T when 'T: not struct>() =

let factory = new WebApplicationFactory<'T>()
Expand Down
2 changes: 1 addition & 1 deletion ApiStub.FSharp/Csharp.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ApiStub.Fsharp
namespace ApiStub.Fsharp.CSharp

open System.Runtime.CompilerServices
open ApiStub.FSharp.CE
Expand Down
8 changes: 8 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<PropertyGroup>
<RepositoryUrl>https://github.com/jkone27/fsharp-integration-tests</RepositoryUrl>
<FsDocsLicenseLink>https://raw.githubusercontent.com/jkone27/fsharp-integration-tests/refs/heads/main/LICENSE</FsDocsLicenseLink>
<FsDocsReleaseNotesLink>https://github.com/jkone27/fsharp-integration-tests/blob/master/RELEASE_NOTES.md</FsDocsReleaseNotesLink>
<PackageProjectUrl>https://github.com/jkone27/fsharp-integration-tests</PackageProjectUrl>
</PropertyGroup>
</Project>
Loading
Loading