Skip to content

Add Hedgehog.MSTest: Property attributes for MSTest 4 - #487

Merged
AlexeyRaga merged 12 commits into
hedgehogqa:masterfrom
xperiandri:mstest-adapter
Oct 13, 2026
Merged

AlexeyRaga merged 12 commits into
hedgehogqa:masterfrom
xperiandri:mstest-adapter

Conversation

@xperiandri

@xperiandri xperiandri commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

This adds Hedgehog.MSTest, a third adapter next to Hedgehog.NUnit and Hedgehog.Xunit. It has the same attributes – [<Property>], [<Properties>], [<Recheck>], GenAttribute<'a> and the built-in generator attributes such as Int, PositiveInt and Email – and the same settings: AutoGenConfig, AutoGenConfigArgs, Tests, Shrinks and Size.

[<TestClass>]
type ReverseTests() =

    [<Property>]
    member _.``reverse twice is identity`` (xs: int list) =
        Assert.AreEqual<int list>(xs, List.rev (List.rev xs))

CONTRIBUTING asks for a discussion before a significant change. I am opening this as a pull request so that the discussion has code to look at; I am happy to move it to a discussion, or to cut it down.

How it works

PropertyAttribute derives from MSTest's TestMethodAttribute and overrides ExecuteAsync, which MSTest calls instead of invoking the test method once. Hedgehog generates the arguments, every case and every shrink step is one ITestMethod.InvokeAsync call, and the whole run is reported as a single TestResult. A failure carries Hedgehog's report, the exception and the output of the counterexample, and a [<Recheck("…")>] line to paste.

The commits are meant to be read in order. The first one copies the framework-neutral files of Hedgehog.NUnit with only the namespace renamed, so the later ones show exactly what differs.

What MSTest forces to be different

  • Return types. MSTest 4 runs only test methods that return void, Task or ValueTask; one method that returns anything else fails the discovery of the whole test assembly (UTA007). So a property fails by throwing, and the handling of bool, Property<_>, Result, Async and Task<'T> results is gone. For the same reason properties are instance members of [<TestClass>] types: MSTest has no module-level tests.
  • Generic methods get an error result. MSTest discovers them, but closing them over obj, as the other two adapters do, makes every generated value null.
  • Lifecycle. Every case goes through InvokeAsync, so MSTest creates the test class and runs TestInitialize and TestCleanup for every case and every shrink step, and a [<Timeout>] applies to each invocation. Because of that, each node of the shrink tree is invoked exactly once: the property runner evaluates an asynchronous result again whenever it unwraps it, which would otherwise run the counterexample, with its setup and cleanup, twice.
  • Inherited properties. MSTest runs a property declared in a base class once per derived test class. The class-level [<Properties>] are therefore read from the class that MSTest runs (MethodInfo.ReflectedType), and those of a derived class win over its base's.
  • Cancellation. Once the cancellation token of the TestContext is cancelled, by a timeout or by the test run, the property stops without shrinking. The token is checked before every invocation and after it, whatever its outcome, because MSTest reports a test method that returns without observing its cancelled token as passed. An attribute reaches the token only through TestContext.Current, which MSTest 4.1 does not have yet and which is marked experimental (MSTESTEXP).
  • Invocations that MSTest could not run. InvokeAsync can end with an outcome that is not the test method's own, such as Error or NotFound, or throw. That is not a counterexample: the property stops at it without shrinking and reports the outcome and the exception of that invocation as they are.

What it adds to the other two adapters

Each of these can be ported to Hedgehog.NUnit and Hedgehog.Xunit, or dropped here if you prefer the three adapters to match:

  • Seed on Property and Properties, passed on through PropertyConfig.withSeed, so that a suite can fix its seed.
  • Data rows. The values of a [<DataRow>] or [<DynamicData>] row are the leading arguments, and only the parameters after them are generated.
  • Assert.Inconclusive in a case discards the case, like a precondition that does not hold.
  • Generator attributes in an inheritance chain. A GenAttribute is found through a non-generic base type. The other two adapters check only the direct base type, so an attribute derived from, say, IntAttribute is overlooked and the parameter is auto-generated.
  • [<DateOnly>] and [<TimeOnly>], the two attributes that Generate DateOnly and TimeOnly: Gen functions, auto-generation and attributes #488 adds to Hedgehog.Xunit and Hedgehog.NUnit. Here they generate over the day number and the ticks themselves, so that this pull request does not depend on Generate DateOnly and TimeOnly: Gen functions, auto-generation and attributes #488.

Three fixes in the copied files

Each is a separate commit, and Hedgehog.NUnit and Hedgehog.Xunit have the same code. I can send the fixes for those two as a follow-up, or take them out of this pull request.

  • NonZeroInt with 0 as a bound of its range generates 0 and a value outside the range: NonZeroInt(0, 5) gives -1 and 0, NonZeroInt(-5, 0) gives 0 and 1.
  • A generic AutoGenConfig method does not get its type arguments from AutoGenConfigArgs when one generic parameter types two parameters, or when it is nested in a parameter type such as 'a[].
  • Odd and Even can leave their range by one: Odd(-1, 0) gives 1, Even(1, 2) gives 0. They now generate from the odd or even values inside the range and reject a range without one.

Testing

  • tests/Hedgehog.MSTest.Tests.FSharp, 142 tests: the xUnit and NUnit suites rewritten for MSTest, plus tests of everything listed above. A property that fails by design is driven through the adapter's entry point and its result is asserted, so it does not fail the suite.
  • tests/Hedgehog.MSTest.Tests.FSharp.MinimumMSTest compiles the same test files against MSTest 4.2.3, so the solution runs the suite on the oldest supported MSTest and on the current one.
  • tests/Hedgehog.MSTest.Tests.CSharp, 36 tests, after the model of Hedgehog.Xunit.Tests.CSharp: the generator attributes, the settings as named arguments and as constructor arguments, an AutoGenConfig type, a GenAttribute declared in C#, data rows, Recheck, and properties that return Task and ValueTask.
  • Run with SDK 8.0.416 on MSTest 4.2.3, 4.3.2 and 4.5.1. The package references MSTest.TestFramework 4.2.3, the lowest version I tested that has TestContext.Current; the test projects reference 4.5.1, except the one named above.
  • dotnet build and dotnet test of the whole solution pass locally.

Things to know before merging

  • master.yml packs and pushes every package, so a merge publishes Hedgehog.MSTest 1.0.0. The id is not taken on nuget.org.
  • Authors names me next to Alexey Raga, whose code most of the shared files are. Change it as you see fit.
  • The documentation is one short MSTest section in the getting started guide. Its F# example calls Property.checkBool; the xUnit and NUnit examples next to it call Property.check on a Property<bool>, which does not compile.
  • dotnet fsi gen-docfx.fsx Release fails for me before it reaches anything this pull request touches, while it loads Hedgehog.dll: the script does not pin FSharp.Formatting, and its current release needs a newer FSharp.Compiler.Service than the pinned 43.8.400. CI may hit the same.

The adapter was written for fsprojects/FSharp.Azure.Cosmos, where it lives as a test-only project until there is a package.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings October 10, 2026 11:08
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Terminal MSTest outcomes are misclassified, and bounded odd/even generators can emit values outside their requested ranges.

2 open findings
What changed in this PR

Adds a Hedgehog adapter for MSTest 4, including property attributes, generators, lifecycle integration, documentation, and comprehensive F# tests.

Changes:

  • Adds MSTest property execution, configuration, shrinking, replay, data-row, and cancellation support.
  • Adds built-in generator attributes and adapter test coverage.
  • Integrates the projects into the solution and documentation.
File Description
src/​Hedgehog.MSTest/​AutoGenConfig.fs Instantiates custom generator configurations.
src/​Hedgehog.MSTest/​GenAttribute.fs Defines generator attribute abstractions.
src/​Hedgehog.MSTest/​GenAttribute.Prelude.fs Adds built-in generator attributes.
src/​Hedgehog.MSTest/​Hedgehog.MSTest.fsproj Configures the adapter package.
src/​Hedgehog.MSTest/​InternalLogic.fs Implements property execution and result reporting.
src/​Hedgehog.MSTest/​IPropertyAttribute.fs Defines shared property settings.
src/​Hedgehog.MSTest/​Prelude.fs Adds internal utility helpers.
src/​Hedgehog.MSTest/​PropertiesAttribute.fs Adds class-level property defaults.
src/​Hedgehog.MSTest/​PropertyAttribute.fs Adds the MSTest property attribute.
src/​Hedgehog.MSTest/​PropertyContext.fs Resolves effective property configuration.
src/​Hedgehog.MSTest/​RecheckAttribute.fs Adds failure replay metadata.
src/​Hedgehog.MSTest/​ReflectionHelpers.fs Adds return-type reflection helpers.
tests/​Hedgehog.MSTest.Tests.FSharp/​Common.fs Provides shared test fixtures.
tests/​Hedgehog.MSTest.Tests.FSharp/​GenAttributePreludeTests.fs Tests built-in generators.
tests/​Hedgehog.MSTest.Tests.FSharp/​Harness.fs Provides adapter-level test execution.
tests/​Hedgehog.MSTest.Tests.FSharp/​Hedgehog.MSTest.Tests.FSharp.fsproj Configures the MSTest suite.
tests/​Hedgehog.MSTest.Tests.FSharp/​MSTestTests.fs Tests MSTest-specific behavior.
tests/​Hedgehog.MSTest.Tests.FSharp/​PropertyTests.fs Tests property configuration and shrinking.
docs/​articles/​getting-started.md Documents MSTest usage.
Hedgehog.sln Registers the new projects.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Hedgehog.MSTest/InternalLogic.fs Resolved
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, as the review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. Prelude loses Option.requireSome and Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.

Two things stay upstream's, so that the two copies remain comparable:
the formatting, which is why .fantomasignore keeps the project, and
nullness checking, which is off as in every upstream project. The header
of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, as the review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. Prelude loses Option.requireSome and Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.

Two things stay upstream's, so that the two copies remain comparable:
the formatting, which is why .fantomasignore keeps the project, and
nullness checking, which is off as in every upstream project. The header
of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, as the review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. Prelude loses Option.requireSome and Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.

Two things stay upstream's, so that the two copies remain comparable:
the formatting, which is why .fantomasignore keeps the project, and
nullness checking, which is off as in every upstream project. The header
of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, as the review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. Prelude loses Option.requireSome and Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

Two things stay upstream's, so that the two copies remain comparable:
the formatting, which is why .fantomasignore keeps the project, and
nullness checking, which is off as in every upstream project. The header
of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri and others added 10 commits October 10, 2026 16:17
The sources that do not depend on the test framework are copied from
Hedgehog.NUnit with only the namespace renamed, so that the following
commits show what MSTest changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PropertyAttribute derives from TestMethodAttribute and overrides
ExecuteAsync, which MSTest calls instead of invoking the test method
once. Hedgehog generates the arguments, every case and every shrink step
is one ITestMethod.InvokeAsync call, and the run is folded into a single
TestResult whose message is Hedgehog's report, followed by a Recheck
attribute that replays the failure.

What MSTest makes different from Hedgehog.NUnit:

- MSTest runs only test methods that return void, Task or ValueTask, so
  the handling of bool, Property, Result, Async and Task<'T> results is
  gone and a property fails by throwing. A generic method gets an error
  result instead of arguments that are all null.
- The values of a DataRow or DynamicData row are the leading arguments,
  and only the parameters after them are generated.
- MSTest creates the test class and runs TestInitialize and TestCleanup
  for every invocation. Each node of the shrink tree is therefore
  invoked once: the property runner evaluates an asynchronous result
  again whenever it unwraps it, which would run the counterexample
  twice.
- An invocation that calls Assert.Inconclusive is discarded.
- The run stops without shrinking once the cancellation token of the
  TestContext is cancelled, by a Timeout or by the test run.
  The token is checked before every invocation and after it, whatever
  the outcome: MSTest reports a test method that returns without
  observing its cancelled token as passed.
- An invocation whose outcome is none of Passed, Failed, Inconclusive
  and Timeout, such as Error, was not run as a test by MSTest. The run
  stops at it without shrinking, and the property reports the outcome
  and the exception of that invocation instead of a counterexample.
- MSTest runs a property inherited from a base class once per derived
  test class, so the class-level settings come from the reflected type
  of the method, and those of a derived class win over its base's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generator of a parameter was found only when the attribute derived
from GenAttribute<'a> directly: an attribute derived from another
generator attribute, such as one derived from IntAttribute, was
overlooked and the parameter was auto-generated instead. A non-generic
base GenAttribute declares Box, so the attribute is found by a type
test wherever it sits in the inheritance chain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A seed on the attribute, passed on through PropertyConfig.withSeed,
makes every run of a property generate the same cases, for example one
seed per suite on its Properties attribute. Without it every run draws
a random seed, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NonZeroInt splits a range that contains 0 into the part below it and
the part above it. With 0 as the lowest or the highest value, one of the
parts is empty, and its inverted range still generated values:
NonZeroInt(0, 5) gave -1 and 0, NonZeroInt(-5, 0) gave 0 and 1. Such a
range now skips the 0 at its end, and the range from 0 to 0, which holds
no non-zero value, is rejected.

Hedgehog.NUnit and Hedgehog.Xunit have the same code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eters

The type arguments of a generic config method were the types of the
AutoGenConfigArgs whose parameter type is itself a generic parameter,
one per such parameter. That fails when one generic parameter types two
parameters, and when it is nested in a parameter type such as 'a[].
The types of the arguments are now unified with the parameter types,
through arrays and generic types, and a generic parameter that gets two
different types, or none, is reported by name.

Hedgehog.NUnit and Hedgehog.Xunit have the same code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The suites of Hedgehog.Xunit and Hedgehog.NUnit rewritten for MSTest,
without the cases MSTest cannot run (properties that return bool,
Result, Async, Task<'T> or a Property, module-level and generic
properties), plus tests of what the MSTest adapter adds or does
differently: one result per property, the lifecycle of every case,
failure reports and their replay, Seed, give-ups, Assert.Inconclusive,
rejected methods, data rows, settings of inherited properties, generator
attributes in an inheritance chain, memoised invocations, cancellation,
timeouts and invocations that MSTest could not run.

A property that fails by design lives in a class without TestClass and
runs through the adapter's entry point with an invoker of the suite's
own, so that its result is asserted instead of failing the suite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An MSTest section next to xUnit and NUnit, with a note on the Property
attribute of Hedgehog.MSTest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DateOnlyAttribute and TimeOnlyAttribute set the generator of one
parameter from a minimum to a maximum, both included. Without arguments
DateOnly generates within the 3650 days from 2000-01-01, the dates of
DateTimeAttribute's default range, and TimeOnly any time of day.

An attribute argument must be a constant, so it cannot be a DateOnly or
a TimeOnly. Both attributes therefore also take their range as
integers, [<DateOnly(2024, 1, 1, 2024, 12, 31)>] and
[<TimeOnly(9, 0, 17, 0)>]; the constructor that takes the two values
serves attributes that derive from these.

Gen.auto cannot generate these two types: it passes arbitrary integers
to their constructors, which throw ArgumentOutOfRangeException. The
attributes therefore generate over the day number and the ticks of the
value themselves, so that they do not depend on a change of the core.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Odd sets the lowest bit of a value generated from min to max, and Even
clears it, so an even upper bound of Odd is exceeded by one and an odd
lower bound of Even is undercut by one: OddAttribute(-1, 0) can give 1,
and EvenAttribute(1, 2) can give 0. The range is now narrowed to its
first and last odd or even value before a value is generated, in 64-bit
arithmetic so that the neighbour of Int32.MinValue or Int32.MaxValue
does not overflow, and a range without such a value, such as
OddAttribute(0, 0), is rejected.

Hedgehog.NUnit and Hedgehog.Xunit have the same code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, as the review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. Prelude loses Option.requireSome and Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

Two things stay upstream's, so that the two copies remain comparable:
the formatting, which is why .fantomasignore keeps the project, and
nullness checking, which is off as in every upstream project. The header
of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, its formatting and nullness checking included, as the
review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. The three files that use them open FSharp.Azure.Cosmos, the
  namespace of these functions. Prelude loses Option.requireSome and
  Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

- The project is formatted with Fantomas: .fantomasignore no longer
  lists it, so the Fantomas run of the build covers it.
- Nullness checking is on, as everywhere in the repository. A data row
  and the arguments of an invocation or of a config method may hold
  null, so they are arrays of objnull. A null array is checked for where
  it enters: in the setters of AutoGenConfigArgs, which take it as no
  arguments, and at the entry point that receives the data row from
  MSTest. Nested exceptions and base types are matched on null instead
  of tested with isNull, reflection lookups that cannot fail are
  asserted with nonNull, and a config method that returns no
  IAutoGenConfig is an error. One call keeps a
  scoped #nowarn "3261", in a helper of its own:
  ITestMethod.InvokeAsync declares the elements of its arguments as
  non-null, although MSTest itself passes it ITestMethod.Arguments,
  whose elements it declares as nullable.
- The pipeline that builds the journal ends in Seq.toArray, so that it
  stays in one module.

The header of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, its formatting and nullness checking included, as the
review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. The three files that use them open FSharp.Azure.Cosmos, the
  namespace of these functions. Prelude loses Option.requireSome and
  Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

- The project is formatted with Fantomas: .fantomasignore no longer
  lists it, so the Fantomas run of the build covers it.
- Nullness checking is on, as everywhere in the repository. A data row
  and the arguments of an invocation or of a config method may hold
  null, so they are arrays of objnull. A null array is checked for where
  it enters: in the setters of AutoGenConfigArgs, which take it as no
  arguments, and at the entry point that receives the data row from
  MSTest. Nested exceptions and base types are matched on null instead
  of tested with isNull, reflection lookups that cannot fail are
  asserted with nonNull, and a config method that returns no
  IAutoGenConfig is an error. One call keeps a
  scoped #nowarn "3261", in a helper of its own:
  ITestMethod.InvokeAsync declares the elements of its arguments as
  non-null, although MSTest itself passes it ITestMethod.Arguments,
  whose elements it declares as nullable.
- The pipeline that builds the journal ends in Seq.toArray, so that it
  stays in one module.

The header of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 10, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 11, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, its formatting and nullness checking included, as the
review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. The three files that use them open FSharp.Azure.Cosmos, the
  namespace of these functions. Prelude loses Option.requireSome and
  Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

- The project is formatted with Fantomas: .fantomasignore no longer
  lists it, so the Fantomas run of the build covers it.
- Nullness checking is on, as everywhere in the repository. A data row
  and the arguments of an invocation or of a config method may hold
  null, so they are arrays of objnull. A null array is checked for where
  it enters: in the setters of AutoGenConfigArgs, which take it as no
  arguments, and at the entry point that receives the data row from
  MSTest. Nested exceptions and base types are matched on null instead
  of tested with isNull, reflection lookups that cannot fail are
  asserted with nonNull, and a config method that returns no
  IAutoGenConfig is an error. One call keeps a
  scoped #nowarn "3261", in a helper of its own:
  ITestMethod.InvokeAsync declares the elements of its arguments as
  non-null, although MSTest itself passes it ITestMethod.Arguments,
  whose elements it declares as nullable.
- The pipeline that builds the journal ends in Seq.toArray, so that it
  stays in one module.

The header of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 11, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The attributes are meant for C# as well: their settings have getters
only so that C# accepts them as named arguments. The F# tests do not
show that a C# test project compiles against them and that MSTest
discovers and runs what it declares.

Hedgehog.MSTest.Tests.CSharp does, after the model of
Hedgehog.Xunit.Tests.CSharp: the generator attributes, the settings of
Property and Properties as named arguments and as constructor
arguments, an AutoGenConfig with and without arguments, a GenAttribute
declared in C#, data rows before the generated arguments, Recheck, and
properties that return Task and ValueTask. The number of cases that a
setting asks for is counted and checked when the class is cleaned up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 11, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, its formatting and nullness checking included, as the
review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. The three files that use them open FSharp.Azure.Cosmos, the
  namespace of these functions. Prelude loses Option.requireSome and
  Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

- The project is formatted with Fantomas: .fantomasignore no longer
  lists it, so the Fantomas run of the build covers it.
- Nullness checking is on, as everywhere in the repository. A data row
  and the arguments of an invocation or of a config method may hold
  null, so they are arrays of objnull. A null array is checked for where
  it enters: in the setters of AutoGenConfigArgs, which take it as no
  arguments, and at the entry point that receives the data row from
  MSTest. Nested exceptions and base types are matched on null instead
  of tested with isNull, reflection lookups that cannot fail are
  asserted with nonNull, and a config method that returns no
  IAutoGenConfig is an error. One call keeps a
  scoped #nowarn "3261", in a helper of its own:
  ITestMethod.InvokeAsync declares the elements of its arguments as
  non-null, although MSTest itself passes it ITestMethod.Arguments,
  whose elements it declares as nullable.
- The pipeline that builds the journal ends in Seq.toArray, so that it
  stays in one module.

The header of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 13, 2026
The adapter was ported in upstream's style, because the same code was to
go into the upstream pull request. That pull request now exists,
hedgehogqa/fsharp-hedgehog#487, with its own copy in upstream's style,
so the copy in this repository follows the coding guidelines of this
repository, its formatting and nullness checking included, as the
review of #43 asks:

- A setting that is not given is a voption instead of an option: the
  members of IPropertyAttribute, the fields of PropertyContext, the
  private constructors and fields of PropertyAttribute and
  PropertiesAttribute, the generic arguments that AutoGenConfig infers
  and the generator that a GenAttribute gives.
- The project compiles src/Shared/ValueCollections.fs again, like every
  other F# project, and uses its Seq.tryHead, Seq.tryFind,
  Seq.tryExactlyOne and Seq.zip, which return a voption or struct
  tuples. The three files that use them open FSharp.Azure.Cosmos, the
  namespace of these functions. Prelude loses Option.requireSome and
  Seq.seqTryExactlyOne.
- The generated arguments are an array instead of a list. Hedgehog 2.0.4
  has Gen.sequence for sequences and Gen.sequenceList for lists, both
  over one traversal, and nothing for arrays, so Prelude adds
  Gen.sequenceArray over Gen.sequence; the values shrink as they did
  through Gen.sequenceList. Type.getAllAttributes returns an array, and
  the two parts of a NonZeroInt range are an array.
- Collections are joined in array and sequence expressions instead of
  Array.append and Seq.append: the arguments of an invocation, the
  values of the journal and the attributes that PropertyContext folds.
- The types that the adapter compares other types with are in one
  module, KnownTypes: Void, Task, ValueTask, IAutoGenConfig and the
  generic definitions of ValueTask<'T>, Async<'T> and Result<'T, 'E>.
  typeof is one ldtoken, but typedefof calls GetGenericTypeDefinition
  on every use (read in the compiled IL), so each type is resolved
  once, and every comparison goes through the operators of System.Type
  instead of generic equality.
- withTests, withShrinks and withSeed are functions with named
  parameters instead of values that hold a lambda.
- Attributes are found through GetCustomAttributes<'T> and OfType<'T>
  instead of a type test and a cast per attribute.
- The error for an AutoGenConfig type without exactly one config member
  says "member" where upstream says "property": a method that takes
  AutoGenConfigArgs is accepted as well (automatic review of #50).

- The project is formatted with Fantomas: .fantomasignore no longer
  lists it, so the Fantomas run of the build covers it.
- Nullness checking is on, as everywhere in the repository. A data row
  and the arguments of an invocation or of a config method may hold
  null, so they are arrays of objnull. A null array is checked for where
  it enters: in the setters of AutoGenConfigArgs, which take it as no
  arguments, and at the entry point that receives the data row from
  MSTest. Nested exceptions and base types are matched on null instead
  of tested with isNull, reflection lookups that cannot fail are
  asserted with nonNull, and a config method that returns no
  IAutoGenConfig is an error. One call keeps a
  scoped #nowarn "3261", in a helper of its own:
  ITestMethod.InvokeAsync declares the elements of its arguments as
  non-null, although MSTest itself passes it ITestMethod.Arguments,
  whose elements it declares as nullable.
- The pipeline that builds the journal ends in Seq.toArray, so that it
  stays in one module.

The header of every changed file records the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AlexeyRaga
AlexeyRaga merged commit 9d08944 into hedgehogqa:master Oct 13, 2026
2 checks passed
@xperiandri
xperiandri deleted the mstest-adapter branch October 13, 2026 14:18
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 13, 2026
Hedgehog.MSTest 1.0.0, the MSTest adapter of Hedgehog
(hedgehogqa/fsharp-hedgehog#487), is released, so a test project
references the package. Hedgehog 2.0.4 is the version that it depends
on. Both get a central version, and the coverage report leaves out their
assemblies, which a property test loads.

The agent instructions list the two packages and say how a property test
is written: a method of a [<TestClass>] type marked [<Property>], with
generated parameters, never Property.check inside a [<TestMethod>]; an
instance method that returns unit, Task or ValueTask and fails by
throwing, because 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; that MSTest runs the test class and its
[<TestInitialize>] and [<TestCleanup>] for every generated case and every
shrink step; and that a failure reports a [<Recheck>] that replays it.
They also say that Hedgehog 2.0.4 cannot generate DateOnly and TimeOnly,
which hedgehogqa/fsharp-hedgehog#488 has merged and not released, so a
parameter of such a type needs a generator of its own.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 13, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 14, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 14, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 14, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 14, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 17, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 17, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 17, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 17, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
The Hedgehog MSTest adapter of #43 is proposed upstream as
hedgehogqa/fsharp-hedgehog#487. The record notes how the proposal
differs from the in-repository copy (net8.0 and F# 8, upstream's
documentation in the shared files, VSTest), that MSTest 4.2 is the
adapter's lowest version, and that one test of #43 stops compiling on
MSTest 4.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xperiandri added a commit to fsprojects/FSharp.Azure.Cosmos that referenced this pull request Oct 18, 2026
hedgehogqa/fsharp-hedgehog#487 is merged and Hedgehog.MSTest 1.0.0 is on
NuGet, so the repository does not carry a copy of the adapter: the pull
request that ported it (#43) is closed, the two adapter projects are not
added, and the test projects reference the package. The record says
which commits of #43 live on in #50 and #54, what the property tests of
the stack run on now, and that Hedgehog 2.0.4 still cannot generate
DateOnly and TimeOnly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants