Add snapshotList syntax for sequences (#25)

This commit is contained in:
Patrick Stevens
2025-07-30 09:11:36 +01:00
committed by GitHub
parent faacb4770c
commit ebc24f85aa
12 changed files with 777 additions and 34 deletions

View File

@@ -1,5 +1,6 @@
namespace WoofWare.Expect
open System.Collections
open System.Text.Json
open System.Text.Json.Serialization
@@ -34,6 +35,15 @@ type ExpectState<'T> =
Actual : (unit -> 'T) option
}
/// The state accumulated by the `expect` builder. You should never find yourself interacting with this type.
type ExpectStateListy<'T> =
private
{
Formatter : ((unit -> 'T) -> string) option
Snapshot : (string list * CallerInfo) option
Actual : (unit -> 'T seq) option
}
/// The state accumulated by the `expect` builder. You should never find yourself interacting with this type.
type internal CompletedSnapshotGeneric<'T> =
private
@@ -126,18 +136,69 @@ module internal CompletedSnapshotGeneric =
else
None
/// Represents a snapshot test that has failed and is awaiting update or report to the user.
type CompletedSnapshot =
internal
type internal CompletedListSnapshotGeneric<'elt> =
private
{
CallerInfo : CallerInfo
Replacement : string
Expected : string list
Format : 'elt -> string
Caller : CallerInfo
Actual : unit -> 'elt seq
}
[<RequireQualifiedAccess>]
module internal CompletedSnapshot =
let make (s : CompletedSnapshotGeneric<'T>) =
module internal CompletedListSnapshotGeneric =
let replacement (s : CompletedListSnapshotGeneric<'T>) =
s.Actual () |> unbox<IEnumerable> |> Seq.cast |> Seq.map s.Format |> Seq.toList
/// Returns None if the assertion passes, or Some (expected, actual) if the assertion fails.
let internal passesAssertion (state : CompletedListSnapshotGeneric<'T>) : (string list * string list) option =
let actual =
state.Actual ()
|> unbox<IEnumerable>
|> Seq.cast
|> Seq.map state.Format
|> Seq.toList
if state.Expected <> actual then
Some (state.Expected, actual)
else
None
let make (state : ExpectStateListy<'elt>) : CompletedListSnapshotGeneric<'elt> =
match state.Actual with
| None -> failwith "expected an assertion, but got none"
| Some actual ->
match state.Snapshot with
| None -> failwith "expected a snapshotList, but got none"
| Some (snapshot, caller) ->
let formatter =
match state.Formatter with
| Some f -> fun x -> f (fun () -> x)
| None -> fun x -> x.ToString ()
{
CallerInfo = s.Caller
Replacement = CompletedSnapshotGeneric.replacement s
Expected = snapshot
Format = formatter
Caller = caller
Actual = actual
}
/// Represents a snapshot test that has failed and is awaiting update or report to the user.
type internal CompletedSnapshot =
| GuessString of CallerInfo * replacement : string
| Known of CallerInfo * replacement : string list * SnapshotLocation
member this.CallerInfo =
match this with
| CompletedSnapshot.GuessString (c, _) -> c
| CompletedSnapshot.Known (c, _, _) -> c
[<RequireQualifiedAccess>]
module internal CompletedSnapshot =
let makeGuess (s : CompletedSnapshotGeneric<'T>) =
CompletedSnapshot.GuessString (s.Caller, CompletedSnapshotGeneric.replacement s)
let makeFromAst (source : SnapshotLocation) (s : CompletedListSnapshotGeneric<'elt>) =
CompletedSnapshot.Known (s.Caller, CompletedListSnapshotGeneric.replacement s, source)