Skip to content
Open
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: 6 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
│ └── ValueCollections.fs – `Seq`, `List` and `Array` functions that return `voption` and struct tuples
├── tests/Cosmos.Tests/ – MSTest integration test project
├── tests/Cosmos.Tests.Infrastructure/ – shared test fixtures, emulator settings and assertion helpers
├── tests/Hedgehog.MSTest/ – Hedgehog MSTest adapter for [<Property>] test methods (from hedgehogqa/fsharp-hedgehog)
├── tests/Hedgehog.MSTest.Tests/ – the adapter's own test suite
├── build/ – FAKE build scripts
└── docsSrc/ – FSharp.Formatting documentation source
```
Expand All @@ -40,6 +42,7 @@
* [`FSharp.Control.Reactive`](https://github.com/fsprojects/FSharp.Reactive) – Rx extensions for F#
* [`FsToolkit.ErrorHandling`](https://github.com/demystifyfp/FsToolkit.ErrorHandling) – `taskResult`, `Result`, `voption` CEs
* [`Unquote`](https://github.com/SwensenSoftware/unquote) – test assertions
* [`Hedgehog`](https://github.com/hedgehogqa/fsharp-hedgehog) – property-based testing through the `tests/Hedgehog.MSTest` adapter
* [`MSTest`](https://github.com/microsoft/testfx) – test framework

Use GitHub MCP tools for code search in these repositories when needed.
Expand Down Expand Up @@ -238,7 +241,9 @@ module MyTypeExtensions =
* `COSMOS_EMULATOR_PARTITION_COUNT` is the number of partitions the emulator offers (default `25`, the Windows emulator's default `/PartitionCount`); the fixtures keep at most that many test containers at a time, one partition each.
* `COSMOS_TEST_LEFTOVER_AGE_MINUTES` is how many minutes a `fsac-test-` database must stay unmodified before the leftover sweep of `[<AssemblyInitialize>]` and `[<AssemblyCleanup>]` deletes it (default `60`), so that the live databases of another test process on the same emulator are kept; `0` deletes every test database and is safe only while no other test process uses the emulator.
* `COSMOS_REWRITE_BASELINES` set to `1` or `true` makes a test that compares SQL with its golden baseline (`Baseline.assertMatches`, files under `Baselines/<suite>/` of the test project) write what it produced into the baseline instead of comparing; the test then reports itself inconclusive, the rewritten files are reviewed in the diff, and CI refuses to rewrite.
* Every test project under `tests/` references `tests/Cosmos.Tests.Infrastructure` through `tests/Directory.Build.props`; a new test project gets it without a `ProjectReference` of its own.
* Every test project under `tests/` references `tests/Cosmos.Tests.Infrastructure` through `tests/Directory.Build.props`; a new test project gets it without a `ProjectReference` of its own. The Hedgehog MSTest adapter and its suite are the exception: they stay free of the Cosmos projects, and the suite references the adapter alone.
* Property tests are methods of `[<TestClass>]` types marked `[<Property>]` (from `tests/Hedgehog.MSTest`), whose parameters Hedgehog generates; never call `Property.check` inside a `[<TestMethod>]`. A test project with property tests references the adapter project and the `Hedgehog` package, as `tests/Cosmos.Tests` does. A property is an instance method that returns `unit`, `Task` or `ValueTask` and fails by throwing: MSTest 4 rejects static methods and other return types, and one such method fails the discovery of the whole assembly, which `--list-tests` shows before a run. MSTest creates the test class and runs `[<TestInitialize>]` and `[<TestCleanup>]` for every generated case and every shrink step. A failed property reports a `[<Recheck("…")>]` to add next to its `Property` attribute, which then replays the counterexample. A parameter of type `DateOnly` or `TimeOnly`, or of a type that holds one, is generated like any other, and `[<DateOnly>]` and `[<TimeOnly>]` bound its value: Hedgehog 2.0.4 has no generator of the two types, so the adapter registers the ones that [hedgehogqa/fsharp-hedgehog#488](https://github.com/hedgehogqa/fsharp-hedgehog/pull/488) adds to Hedgehog, until a release has them. `Gen.auto` outside a property does not know the two types before that release.
* `tests/Hedgehog.MSTest` and `tests/Hedgehog.MSTest.Tests` are ported from hedgehogqa/fsharp-hedgehog and proposed there too ([hedgehogqa/fsharp-hedgehog#487](https://github.com/hedgehogqa/fsharp-hedgehog/pull/487)). Their code follows the rules of this file, formatting with Fantomas and nullness checking included; the copy in the upstream pull request keeps upstream's style, so a change of behaviour goes into both. Copied files keep their Apache-2.0 header, which records every change made to them, and `THIRD-PARTY-NOTICES.md` lists them.
* `CollectionAssert` cannot work with F# lists – use F# array syntax (`[| ... |]`) instead.
* `StringAssert` has overloads with `StringComparison`.
* Use `Assert.Contains` instead of `Assert.IsTrue (str.Contains ..., "message")`, and do not put the actual value into the message.
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<PackageVersion Include="Fake.DotNet.Paket" Version="6.2.0" />
<PackageVersion Include="Fake.IO.FileSystem" Version="6.2.0" />
<PackageVersion Include="Fake.Tools.Git" Version="6.2.0" />
<PackageVersion Include="Hedgehog" Version="2.0.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.401" />
<PackageVersion Include="MSTest" Version="4.2.3" />
Expand Down
4 changes: 3 additions & 1 deletion FSharp.Azure.Cosmos.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"projects": [
"src\\Cosmos\\FSharp.Azure.Cosmos.fsproj",
"tests\\Cosmos.Tests.Infrastructure\\FSharp.Azure.Cosmos.Tests.Infrastructure.fsproj",
"tests\\Cosmos.Tests\\FSharp.Azure.Cosmos.Tests.fsproj"
"tests\\Cosmos.Tests\\FSharp.Azure.Cosmos.Tests.fsproj",
"tests\\Hedgehog.MSTest\\Hedgehog.MSTest.fsproj",
"tests\\Hedgehog.MSTest.Tests\\Hedgehog.MSTest.Tests.fsproj"
]
}
}
3 changes: 3 additions & 0 deletions FSharp.Azure.Cosmos.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
<File Path="Directory.Packages.props" />
<File Path="global.json" />
<File Path="README.md" />
<File Path="THIRD-PARTY-NOTICES.md" />
</Folder>
<Project Path="build/build.fsproj" />
<Project Path="src/Cosmos/FSharp.Azure.Cosmos.fsproj" />
<Project Path="tests/Cosmos.Tests.Infrastructure/FSharp.Azure.Cosmos.Tests.Infrastructure.fsproj" />
<Project Path="tests/Cosmos.Tests/FSharp.Azure.Cosmos.Tests.fsproj" />
<Project Path="tests/Hedgehog.MSTest/Hedgehog.MSTest.fsproj" />
<Project Path="tests/Hedgehog.MSTest.Tests/Hedgehog.MSTest.Tests.fsproj" />
</Solution>
35 changes: 35 additions & 0 deletions THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Third-party notices

This repository contains code copied from the projects below. Each copied file names its origin and the changes made
to it in a header comment. The rest of the repository is covered by [LICENSE](LICENSE).

## fsharp-hedgehog

* Source: <https://github.com/hedgehogqa/fsharp-hedgehog>, release commit
[`a46977278db9a60542e3df3fe0fcd74b90f38ee3`](https://github.com/hedgehogqa/fsharp-hedgehog/tree/a46977278db9a60542e3df3fe0fcd74b90f38ee3)
(Hedgehog 2.0.4; the repository has no tag for this release)
* Copied into: `tests/Hedgehog.MSTest` (the Hedgehog MSTest adapter), from `src/Hedgehog.NUnit`: `Prelude.fs`,
`ReflectionHelpers.fs`, `AutoGenConfig.fs`, `IPropertyAttribute.fs`, `RecheckAttribute.fs`, `GenAttribute.fs`,
`GenAttribute.Prelude.fs`, `PropertyContext.fs`, `InternalLogic.fs`, `PropertiesAttribute.fs` and, adapted from
NUnit to MSTest, `PropertyAttribute.fs`
* Ported into: `tests/Hedgehog.MSTest.Tests` (the adapter's suite), rewritten for MSTest, from
`tests/Hedgehog.Xunit.Tests.FSharp/PropertyTests.fs`, `tests/Hedgehog.NUnit.Tests.FSharp/PropertyTests.fs` and
`tests/Hedgehog.NUnit.Tests.FSharp/GenAttributePreludeTests.fs`: `Common.fs`, `PropertyTests.fs` and
`GenAttributePreludeTests.fs`
* License: Apache License, Version 2.0

```text
Copyright (c) 2016 Jacob Stanley, Nikos Baxevanis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
57 changes: 37 additions & 20 deletions build/build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -354,32 +354,46 @@ let fsharpAnalyzers _ =
dotnet.fsharpAnalyzer id args
)

let dotnetTest ctx =
// Create test results directory if it doesn't exist
Directory.create testResultsDir

/// <summary>
/// Runs <c>dotnet test</c> with the Microsoft.Testing.Platform runner for every test application, without building, in
/// the configuration of the executing targets and with the options that <paramref name="configure"/> changes.
/// </summary>
let dotnetTestApplications ctx (configure : DotNet.MTPTestOptions -> DotNet.MTPTestOptions) =
let dotnetConfiguration = configuration (ctx.Context.AllExecutingTargets)

!!testsGlob
|> Seq.iter (fun testProject ->
DotNet.testMTP
(fun options -> {
options with
NoBuild = true
Configuration = Some dotnetConfiguration
ResultsDirectory = if enableCodeCoverage then Some testResultsDir else None
CodeCoverage =
if enableCodeCoverage then
Some {
DotNet.MTPCodeCoverageOptions.Create () with
OutputFormat = Some DotNet.MTPCoverageFormat.Cobertura
}
else
None
})
(fun options -> configure { options with NoBuild = true; Configuration = Some dotnetConfiguration })
(DotNet.MTPTestTarget.Project testProject)
)

let dotnetTest ctx =
// Create test results directory if it doesn't exist
Directory.create testResultsDir

dotnetTestApplications
ctx
(fun options -> {
options with
ResultsDirectory = if enableCodeCoverage then Some testResultsDir else None
CodeCoverage =
if enableCodeCoverage then
Some {
DotNet.MTPCodeCoverageOptions.Create () with
OutputFormat = Some DotNet.MTPCoverageFormat.Cobertura
}
else
None
})

/// <summary>
/// Lists the tests of every test application without running them. MSTest 4 fails the discovery of a whole assembly
/// when one test method has a signature that it cannot run, such as a property method that returns a value, and the F#
/// build gives no warning for it; listing reports that before the run, which needs the emulator, starts.
/// </summary>
let dotnetListTests ctx = dotnetTestApplications ctx (fun options -> { options with ListTests = true })

let generateCoverageReport _ =

let coverageFiles =
Expand All @@ -393,8 +407,8 @@ let generateCoverageReport _ =
sprintf "-targetdir:\"%s\"" coverageReportDir
// Add source dir
sprintf "-sourcedirs:\"%s\"" sourceDirs
// Ignore test assemblies and the helper libraries they share
sprintf "-assemblyfilters:\"%s\"" "-*.Tests;-*.Tests.Infrastructure"
// Ignore test assemblies, the helper libraries they share, the Hedgehog MSTest adapter and Hedgehog itself
sprintf "-assemblyfilters:\"%s\"" "-*.Tests;-*.Tests.Infrastructure;-Hedgehog;-Hedgehog.MSTest"
// Generate HTML and Cobertura reports
sprintf "-reporttypes:%s" "Html;Cobertura"
]
Expand Down Expand Up @@ -640,6 +654,7 @@ let initTargets (ctx : Context.FakeExecutionContext) =
Target.createFinal "DeleteChangelogBackupFile" deleteChangelogBackupFile // Do NOT put this in the dependency chain
Target.create "DotnetBuild" dotnetBuild
Target.create "FSharpAnalyzers" fsharpAnalyzers
Target.create "DotnetListTests" dotnetListTests
Target.create "DotnetTest" dotnetTest
Target.create "GenerateCoverageReport" generateCoverageReport
Target.create "ShowCoverageReport" showCoverageReport
Expand Down Expand Up @@ -701,6 +716,7 @@ let initTargets (ctx : Context.FakeExecutionContext) =

"DotnetRestore" =?> ("CheckFormatCode", isCI.Value)
==> "DotnetBuild"
==> "DotnetListTests"
==> "DotnetTest"
==> "DotnetPack"
==> "PublishToNuGet"
Expand All @@ -711,6 +727,7 @@ let initTargets (ctx : Context.FakeExecutionContext) =
=?> ("CheckFormatCode", isCI.Value)
=?> ("GenerateAssemblyInfo", isPublishToGitHub)
==> "DotnetBuild"
==> "DotnetListTests"
==> "DotnetTest"
==> "DotnetPack"
==>! "PublishToGitHub"
Expand Down
3 changes: 3 additions & 0 deletions tests/Cosmos.Tests/FSharp.Azure.Cosmos.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Hedgehog" />
<!-- Referenced directly although the library references it too: the probe tests use IcedTasks themselves and gate which of its builders library code may use, so they must not depend on what the library happens to reference. -->
<PackageReference Include="IcedTasks" />
<PackageReference Include="MSTest" />
Expand All @@ -50,6 +51,8 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Cosmos\FSharp.Azure.Cosmos.fsproj" />
<!-- The Hedgehog MSTest adapter: the [<Property>] attribute that marks the property tests of this project. -->
<ProjectReference Include="..\Hedgehog.MSTest\Hedgehog.MSTest.fsproj" />
</ItemGroup>

</Project>
Loading
Loading