mirror of
https://github.com/Smaug123/WoofWare.Expect
synced 2025-10-07 13:38:39 +00:00
Compare commits
3 Commits
e0153ab182
...
WoofWare.E
Author | SHA1 | Date | |
---|---|---|---|
|
d21786ecd4 | ||
|
ad05a9c106 | ||
|
ed352c1b14 |
@@ -187,6 +187,11 @@ Observe the `OneTimeSetUp` which sets global state to enter "bulk update" mode,
|
|||||||
|
|
||||||
* The snapshot updating mechanism *requires* you to use verbatim string literals. While the test assertions will work correctly if you do `snapshot ("foo" + "bar" + f 3)`, for example, the updating code is liable to do something undefined in that case. Also do not use format strings (`$"blah"`).
|
* The snapshot updating mechanism *requires* you to use verbatim string literals. While the test assertions will work correctly if you do `snapshot ("foo" + "bar" + f 3)`, for example, the updating code is liable to do something undefined in that case. Also do not use format strings (`$"blah"`).
|
||||||
|
|
||||||
|
# Output formats
|
||||||
|
|
||||||
|
* The `Diff` module provides a Patience diff and a Myers diff implementation, which you can use to make certain tests much more readable.
|
||||||
|
* The `Dot` module provides `render`, which renders a dot file as ASCII art. You will need `graph-easy` to use this feature.
|
||||||
|
|
||||||
# Licence
|
# Licence
|
||||||
|
|
||||||
MIT.
|
MIT.
|
||||||
|
110
WoofWare.Expect.Test/TestDot.fs
Normal file
110
WoofWare.Expect.Test/TestDot.fs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
namespace WoofWare.Expect.Test
|
||||||
|
|
||||||
|
#nowarn 0044 // This construct is deprecated
|
||||||
|
|
||||||
|
open System
|
||||||
|
open FsUnitTyped
|
||||||
|
open WoofWare.Expect
|
||||||
|
open NUnit.Framework
|
||||||
|
open System.IO.Abstractions
|
||||||
|
open System.IO.Abstractions.TestingHelpers
|
||||||
|
|
||||||
|
[<TestFixture>]
|
||||||
|
module TestDot =
|
||||||
|
let toFs (fs : IFileSystem) : Dot.IFileSystem =
|
||||||
|
{ new Dot.IFileSystem with
|
||||||
|
member _.DeleteFile s = fs.File.Delete s
|
||||||
|
member _.WriteFile path contents = fs.File.WriteAllText (path, contents)
|
||||||
|
member _.GetTempFileName () = fs.Path.GetTempFileName ()
|
||||||
|
}
|
||||||
|
|
||||||
|
[<Test ; Explicit "requires graph-easy dependency">]
|
||||||
|
let ``Basic dotfile, real graph-easy`` () =
|
||||||
|
let s =
|
||||||
|
"""digraph G {
|
||||||
|
rankdir = TB
|
||||||
|
bgcolor = transparent
|
||||||
|
n2 [shape=box label="{{n2|Map|height=1}}" ]
|
||||||
|
n1 [shape=box label="{{n1|Const|height=0}}" ]
|
||||||
|
n1 -> n2
|
||||||
|
}"""
|
||||||
|
|
||||||
|
expect {
|
||||||
|
snapshot
|
||||||
|
@"
|
||||||
|
┌───────────────────────┐
|
||||||
|
│ {{n1|Const|height=0}} │
|
||||||
|
└───────────────────────┘
|
||||||
|
│
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌───────────────────────┐
|
||||||
|
│ {{n2|Map|height=1}} │
|
||||||
|
└───────────────────────┘
|
||||||
|
"
|
||||||
|
|
||||||
|
return Dot.render s
|
||||||
|
}
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Basic dotfile`` () =
|
||||||
|
let fs = MockFileSystem ()
|
||||||
|
|
||||||
|
let contents =
|
||||||
|
"""digraph G {
|
||||||
|
rankdir = TB
|
||||||
|
bgcolor = transparent
|
||||||
|
n2 [shape=box label="{{n2|Map|height=1}}" ]
|
||||||
|
n1 [shape=box label="{{n1|Const|height=0}}" ]
|
||||||
|
n1 -> n2
|
||||||
|
}"""
|
||||||
|
|
||||||
|
let mutable started = false
|
||||||
|
let mutable waited = false
|
||||||
|
let mutable exitCodeObserved = false
|
||||||
|
let mutable disposed = false
|
||||||
|
|
||||||
|
let expected =
|
||||||
|
"┌───────────────────────┐
|
||||||
|
│ {{n1|Const|height=0}} │
|
||||||
|
└───────────────────────┘
|
||||||
|
│
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌───────────────────────┐
|
||||||
|
│ {{n2|Map|height=1}} │
|
||||||
|
└───────────────────────┘
|
||||||
|
"
|
||||||
|
|
||||||
|
let pr =
|
||||||
|
{ new Dot.IProcess<IDisposable> with
|
||||||
|
member _.Start _ =
|
||||||
|
started <- true
|
||||||
|
true
|
||||||
|
|
||||||
|
member _.Create exe args =
|
||||||
|
exe |> shouldEqual "graph-easy"
|
||||||
|
|
||||||
|
args.StartsWith ("--as=boxart --from=dot ", StringComparison.Ordinal)
|
||||||
|
|> shouldEqual true
|
||||||
|
|
||||||
|
{ new IDisposable with
|
||||||
|
member _.Dispose () = disposed <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
member _.WaitForExit p = waited <- true
|
||||||
|
member _.ReadStandardOutput _ = expected
|
||||||
|
|
||||||
|
member _.ExitCode _ =
|
||||||
|
exitCodeObserved <- true
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
Dot.render' pr (toFs fs) "graph-easy" contents
|
||||||
|
|> _.TrimStart()
|
||||||
|
|> shouldEqual expected
|
||||||
|
|
||||||
|
started |> shouldEqual true
|
||||||
|
waited |> shouldEqual true
|
||||||
|
exitCodeObserved |> shouldEqual true
|
||||||
|
disposed |> shouldEqual true
|
@@ -14,6 +14,7 @@
|
|||||||
<Compile Include="BulkUpdateExample.fs" />
|
<Compile Include="BulkUpdateExample.fs" />
|
||||||
<Compile Include="SimpleTest.fs" />
|
<Compile Include="SimpleTest.fs" />
|
||||||
<Compile Include="TestDiff.fs" />
|
<Compile Include="TestDiff.fs" />
|
||||||
|
<Compile Include="TestDot.fs" />
|
||||||
<Compile Include="TestExceptionThrowing.fs" />
|
<Compile Include="TestExceptionThrowing.fs" />
|
||||||
<Compile Include="TestSurface.fs" />
|
<Compile Include="TestSurface.fs" />
|
||||||
<Compile Include="TestSnapshotFinding\TestSnapshotFinding.fs" />
|
<Compile Include="TestSnapshotFinding\TestSnapshotFinding.fs" />
|
||||||
@@ -40,6 +41,9 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||||
|
<!-- TODO: when ApiSurface accepts https://github.com/G-Research/ApiSurface/pull/116, upgrade these -->
|
||||||
|
<PackageReference Include="System.IO.Abstractions" Version="4.2.13" />
|
||||||
|
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="4.2.13" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -11,45 +11,50 @@ type Position = int<pos>
|
|||||||
|
|
||||||
/// A Patience diff is composed of a sequence of transformations to get from one string to another.
|
/// A Patience diff is composed of a sequence of transformations to get from one string to another.
|
||||||
/// This represents those transformations.
|
/// This represents those transformations.
|
||||||
type DiffOperation =
|
type DiffOperation<'line> =
|
||||||
/// This line is the same on both sides of the diff.
|
/// This line is the same on both sides of the diff.
|
||||||
/// On the left, it appears at position posA. On the right, at position posB.
|
/// On the left, it appears at position posA. On the right, at position posB.
|
||||||
| Match of posA : Position * posB : Position * line : string
|
| Match of posA : Position * posB : Position * line : 'line
|
||||||
/// Delete this line, which is at this position.
|
/// Delete this line, which is at this position.
|
||||||
| Delete of posA : Position * line : string
|
| Delete of posA : Position * line : 'line
|
||||||
/// Insert this line at the given position.
|
/// Insert this line at the given position.
|
||||||
| Insert of posB : Position * line : string
|
| Insert of posB : Position * line : 'line
|
||||||
|
|
||||||
|
/// The diff between two line-oriented streams. Normally the generic parameter will be `string`, indicating
|
||||||
|
/// that the thing being diffed was text.
|
||||||
|
type Diff'<'line> = private | Diff of DiffOperation<'line> list
|
||||||
|
|
||||||
/// The diff between two line-oriented pieces of text.
|
/// The diff between two line-oriented pieces of text.
|
||||||
type Diff = private | Diff of DiffOperation list
|
type Diff = Diff'<string>
|
||||||
|
|
||||||
/// A match between positions in two sequences
|
/// A match between positions in two sequences
|
||||||
type internal LineMatch =
|
type internal LineMatch<'line> =
|
||||||
{
|
{
|
||||||
PosA : Position
|
PosA : Position
|
||||||
PosB : Position
|
PosB : Position
|
||||||
Line : string
|
Line : 'line
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result of finding unique lines in a sequence
|
/// Result of finding unique lines in a sequence
|
||||||
type internal UniqueLines =
|
type internal UniqueLines<'line when 'line : comparison> =
|
||||||
{
|
{
|
||||||
/// Map from line content to its position (only for unique lines)
|
/// Map from line content to its position (only for unique lines)
|
||||||
LinePositions : Map<string, Position>
|
LinePositions : Map<'line, Position>
|
||||||
/// All line counts (for verification)
|
/// All line counts (for verification)
|
||||||
LineCounts : Map<string, int>
|
LineCounts : Map<'line, int>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The diff between two line-oriented pieces of text.
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Diff =
|
module Diff =
|
||||||
/// Find lines that appear exactly once in a sequence
|
/// Find lines that appear exactly once in a sequence
|
||||||
let private findUniqueLines (lines : string array) : UniqueLines =
|
let private findUniqueLines (lines : 'line array) : UniqueLines<'line> =
|
||||||
let positions = Dictionary<string, Position> ()
|
let positions = Dictionary<'line, Position> ()
|
||||||
let counts = Dictionary<string, int> ()
|
let counts = Dictionary<'line, int> ()
|
||||||
|
|
||||||
lines
|
lines
|
||||||
|> Array.iteri (fun i line ->
|
|> Array.iteri (fun i line ->
|
||||||
if counts.ContainsKey (line) then
|
if counts.ContainsKey line then
|
||||||
counts.[line] <- counts.[line] + 1
|
counts.[line] <- counts.[line] + 1
|
||||||
else
|
else
|
||||||
counts.[line] <- 1
|
counts.[line] <- 1
|
||||||
@@ -70,7 +75,7 @@ module Diff =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find longest increasing subsequence based on B positions
|
/// Find longest increasing subsequence based on B positions
|
||||||
let private longestIncreasingSubsequence (matches : LineMatch array) : LineMatch list =
|
let private longestIncreasingSubsequence (matches : LineMatch<'line> array) : LineMatch<'line> list =
|
||||||
let n = matches.Length
|
let n = matches.Length
|
||||||
|
|
||||||
if n = 0 then
|
if n = 0 then
|
||||||
@@ -103,9 +108,8 @@ module Diff =
|
|||||||
|
|
||||||
reconstruct endIndex []
|
reconstruct endIndex []
|
||||||
|
|
||||||
/// Simple Myers diff implementation. You probably want to use `patience` instead, for more human-readable diffs.
|
let private myers' (a : 'line array) (b : 'line array) : DiffOperation<'line> list =
|
||||||
let myers (a : string array) (b : string array) : Diff =
|
let rec diffHelper (i : int) (j : int) (acc : DiffOperation<'line> list) =
|
||||||
let rec diffHelper (i : int) (j : int) (acc : DiffOperation list) =
|
|
||||||
match i < a.Length, j < b.Length with
|
match i < a.Length, j < b.Length with
|
||||||
| false, false -> List.rev acc
|
| false, false -> List.rev acc
|
||||||
| true, false ->
|
| true, false ->
|
||||||
@@ -146,11 +150,14 @@ module Diff =
|
|||||||
// No close match, just delete and insert
|
// No close match, just delete and insert
|
||||||
diffHelper (i + 1) j (Delete (i * 1<pos>, a.[i]) :: acc)
|
diffHelper (i + 1) j (Delete (i * 1<pos>, a.[i]) :: acc)
|
||||||
|
|
||||||
diffHelper 0 0 [] |> Diff
|
diffHelper 0 0 []
|
||||||
|
|
||||||
|
/// Simple Myers diff implementation. You probably want to use `patience` instead, for more human-readable diffs.
|
||||||
|
let myers (a : string array) (b : string array) : Diff = myers' a b |> Diff
|
||||||
|
|
||||||
/// Patience diff: a human-readable line-based diff.
|
/// Patience diff: a human-readable line-based diff.
|
||||||
/// Operates on lines of string; the function `patience` will split on lines for you.
|
/// Operates on lines of string; the function `patience` will split on lines for you.
|
||||||
let rec patienceLines (a : string array) (b : string array) : Diff =
|
let rec patienceLines (a : 'line array) (b : 'line array) : Diff'<'line> =
|
||||||
// Handle empty sequences
|
// Handle empty sequences
|
||||||
match a.Length, b.Length with
|
match a.Length, b.Length with
|
||||||
| 0, 0 -> [] |> Diff
|
| 0, 0 -> [] |> Diff
|
||||||
@@ -177,7 +184,7 @@ module Diff =
|
|||||||
|
|
||||||
if Set.isEmpty commonUniques then
|
if Set.isEmpty commonUniques then
|
||||||
// No unique common lines, fall back to Myers
|
// No unique common lines, fall back to Myers
|
||||||
myers a b
|
myers' a b |> Diff
|
||||||
else
|
else
|
||||||
// Build matches for unique common lines
|
// Build matches for unique common lines
|
||||||
let matches =
|
let matches =
|
||||||
@@ -196,7 +203,7 @@ module Diff =
|
|||||||
let anchorMatches = longestIncreasingSubsequence matches |> List.toArray
|
let anchorMatches = longestIncreasingSubsequence matches |> List.toArray
|
||||||
|
|
||||||
// Build diff imperatively
|
// Build diff imperatively
|
||||||
let result = ResizeArray<DiffOperation> ()
|
let result = ResizeArray<DiffOperation<_>> ()
|
||||||
let mutable prevA = 0<pos>
|
let mutable prevA = 0<pos>
|
||||||
let mutable prevB = 0<pos>
|
let mutable prevB = 0<pos>
|
||||||
|
|
||||||
@@ -244,26 +251,32 @@ module Diff =
|
|||||||
patienceLines (a.Split '\n') (b.Split '\n')
|
patienceLines (a.Split '\n') (b.Split '\n')
|
||||||
|
|
||||||
/// Format the diff as a human-readable string, including line numbers at the left.
|
/// Format the diff as a human-readable string, including line numbers at the left.
|
||||||
let formatWithLineNumbers (Diff ops) : string =
|
let formatWithLineNumbers' (formatter : 'line -> string) (Diff ops) : string =
|
||||||
ops
|
ops
|
||||||
|> List.map (fun op ->
|
|> List.map (fun op ->
|
||||||
match op with
|
match op with
|
||||||
| Match (a, b, line) -> sprintf " %3d %3d %s" a b line
|
| Match (a, b, line) -> sprintf " %3d %3d %s" a b (formatter line)
|
||||||
| Delete (a, line) -> sprintf "- %3d %s" a line
|
| Delete (a, line) -> sprintf "- %3d %s" a (formatter line)
|
||||||
| Insert (b, line) -> sprintf "+ %3d %s" b line
|
| Insert (b, line) -> sprintf "+ %3d %s" b (formatter line)
|
||||||
|
)
|
||||||
|
|> String.concat "\n"
|
||||||
|
|
||||||
|
/// Format the diff as a human-readable string, including line numbers at the left.
|
||||||
|
let formatWithLineNumbers (d : Diff) : string = formatWithLineNumbers' id d
|
||||||
|
|
||||||
|
/// Format the diff as a human-readable string.
|
||||||
|
let format' (formatter : 'line -> string) (Diff ops) : string =
|
||||||
|
ops
|
||||||
|
|> List.map (fun op ->
|
||||||
|
match op with
|
||||||
|
| Match (_, _, line) -> " " + (formatter line)
|
||||||
|
| Delete (_, line) -> "- " + (formatter line)
|
||||||
|
| Insert (_, line) -> "+ " + (formatter line)
|
||||||
)
|
)
|
||||||
|> String.concat "\n"
|
|> String.concat "\n"
|
||||||
|
|
||||||
/// Format the diff as a human-readable string.
|
/// Format the diff as a human-readable string.
|
||||||
let format (Diff ops) : string =
|
let format (ops : Diff) : string = format' id ops
|
||||||
ops
|
|
||||||
|> List.map (fun op ->
|
|
||||||
match op with
|
|
||||||
| Match (_, _, line) -> sprintf " %s" line
|
|
||||||
| Delete (_, line) -> sprintf "- %s" line
|
|
||||||
| Insert (_, line) -> sprintf "+ %s" line
|
|
||||||
)
|
|
||||||
|> String.concat "\n"
|
|
||||||
|
|
||||||
/// Compute diff statistics
|
/// Compute diff statistics
|
||||||
type internal DiffStats =
|
type internal DiffStats =
|
||||||
@@ -274,7 +287,7 @@ module Diff =
|
|||||||
TotalOperations : int
|
TotalOperations : int
|
||||||
}
|
}
|
||||||
|
|
||||||
let internal computeStats (ops : DiffOperation list) : DiffStats =
|
let internal computeStats (ops : DiffOperation<'a> list) : DiffStats =
|
||||||
let counts =
|
let counts =
|
||||||
ops
|
ops
|
||||||
|> List.fold
|
|> List.fold
|
||||||
|
91
WoofWare.Expect/Dot.fs
Normal file
91
WoofWare.Expect/Dot.fs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
namespace WoofWare.Expect
|
||||||
|
|
||||||
|
open System
|
||||||
|
open System.Diagnostics
|
||||||
|
open System.IO
|
||||||
|
|
||||||
|
/// Methods for rendering dot files (specifications of graphs).
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Dot =
|
||||||
|
/// A mock for System.Diagnostics.Process.
|
||||||
|
type IProcess<'Process when 'Process :> IDisposable> =
|
||||||
|
/// Equivalent to Process.Create
|
||||||
|
abstract Create : exe : string -> args : string -> 'Process
|
||||||
|
/// Equivalent to Process.Start
|
||||||
|
abstract Start : 'Process -> bool
|
||||||
|
/// Equivalent to Process.WaitForExit
|
||||||
|
abstract WaitForExit : 'Process -> unit
|
||||||
|
/// Equivalent to Process.StandardOutput.ReadToEnd
|
||||||
|
abstract ReadStandardOutput : 'Process -> string
|
||||||
|
/// Equivalent to Process.ExitCode
|
||||||
|
abstract ExitCode : 'Process -> int
|
||||||
|
|
||||||
|
/// The real Process interface, in a form that can be passed to `render'`.
|
||||||
|
let process' =
|
||||||
|
{ new IProcess<Process> with
|
||||||
|
member _.Create exe args =
|
||||||
|
let psi = ProcessStartInfo exe
|
||||||
|
psi.RedirectStandardOutput <- true
|
||||||
|
psi.Arguments <- args
|
||||||
|
let result = new Process ()
|
||||||
|
result.StartInfo <- psi
|
||||||
|
result
|
||||||
|
|
||||||
|
member _.Start p = p.Start ()
|
||||||
|
member _.WaitForExit p = p.WaitForExit ()
|
||||||
|
member _.ReadStandardOutput p = p.StandardOutput.ReadToEnd ()
|
||||||
|
member _.ExitCode p = p.ExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A mock for System.IO
|
||||||
|
type IFileSystem =
|
||||||
|
/// Equivalent to Path.GetTempFileName
|
||||||
|
abstract GetTempFileName : unit -> string
|
||||||
|
/// Equivalent to File.Delete
|
||||||
|
abstract DeleteFile : string -> unit
|
||||||
|
/// Equivalent to File.WriteAllText (curried)
|
||||||
|
abstract WriteFile : path : string -> contents : string -> unit
|
||||||
|
|
||||||
|
/// The real filesystem, in a form that can be passed to `render'`.
|
||||||
|
let fileSystem =
|
||||||
|
{ new IFileSystem with
|
||||||
|
member _.GetTempFileName () = Path.GetTempFileName ()
|
||||||
|
member _.DeleteFile f = File.Delete f
|
||||||
|
member _.WriteFile path contents = File.WriteAllText (path, contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// writeFile takes the filepath first and the contents second.
|
||||||
|
/// Due to the impoverished nature of the .NET Standard APIs, you are in charge of making sure the output of
|
||||||
|
/// fs.GetTempFileName is suitable for interpolation into a command line.
|
||||||
|
let render'<'Process when 'Process :> IDisposable>
|
||||||
|
(pr : IProcess<'Process>)
|
||||||
|
(fs : IFileSystem)
|
||||||
|
(graphEasyExecutable : string)
|
||||||
|
(dotFileContents : string)
|
||||||
|
: string
|
||||||
|
=
|
||||||
|
let tempFile = fs.GetTempFileName ()
|
||||||
|
|
||||||
|
try
|
||||||
|
fs.WriteFile tempFile dotFileContents
|
||||||
|
|
||||||
|
use p = pr.Create graphEasyExecutable ("--as=boxart --from=dot " + tempFile)
|
||||||
|
pr.Start p |> ignore<bool>
|
||||||
|
pr.WaitForExit p
|
||||||
|
|
||||||
|
let stdout = pr.ReadStandardOutput p
|
||||||
|
let exitCode = pr.ExitCode p
|
||||||
|
|
||||||
|
if exitCode <> 0 then
|
||||||
|
failwithf "failed to run; exit code: %i. stdout:\n%s" exitCode stdout
|
||||||
|
|
||||||
|
"\n" + stdout
|
||||||
|
finally
|
||||||
|
try
|
||||||
|
fs.DeleteFile tempFile
|
||||||
|
with _ ->
|
||||||
|
()
|
||||||
|
|
||||||
|
/// Call `graph-easy` to render the dotfile as ASCII art.
|
||||||
|
/// This is fully mockable, but you must use `render'` to do so.
|
||||||
|
let render = render' process' fileSystem "graph-easy"
|
@@ -8,48 +8,68 @@ WoofWare.Expect.CallerInfo inherit obj, implements WoofWare.Expect.CallerInfo Sy
|
|||||||
WoofWare.Expect.CallerInfo.Equals [method]: (WoofWare.Expect.CallerInfo, System.Collections.IEqualityComparer) -> bool
|
WoofWare.Expect.CallerInfo.Equals [method]: (WoofWare.Expect.CallerInfo, System.Collections.IEqualityComparer) -> bool
|
||||||
WoofWare.Expect.CompletedSnapshot inherit obj, implements WoofWare.Expect.CompletedSnapshot System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Expect.CompletedSnapshot System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
WoofWare.Expect.CompletedSnapshot inherit obj, implements WoofWare.Expect.CompletedSnapshot System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Expect.CompletedSnapshot System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
WoofWare.Expect.CompletedSnapshot.Equals [method]: (WoofWare.Expect.CompletedSnapshot, System.Collections.IEqualityComparer) -> bool
|
WoofWare.Expect.CompletedSnapshot.Equals [method]: (WoofWare.Expect.CompletedSnapshot, System.Collections.IEqualityComparer) -> bool
|
||||||
WoofWare.Expect.Diff inherit obj, implements WoofWare.Expect.Diff System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Expect.Diff System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
WoofWare.Expect.Diff'`1 inherit obj, implements 'line WoofWare.Expect.Diff' System.IEquatable, System.Collections.IStructuralEquatable, 'line WoofWare.Expect.Diff' System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
WoofWare.Expect.Diff.Equals [method]: (WoofWare.Expect.Diff, System.Collections.IEqualityComparer) -> bool
|
WoofWare.Expect.Diff'`1.Equals [method]: ('line WoofWare.Expect.Diff', System.Collections.IEqualityComparer) -> bool
|
||||||
WoofWare.Expect.DiffModule inherit obj
|
WoofWare.Expect.DiffModule inherit obj
|
||||||
WoofWare.Expect.DiffModule.format [static method]: WoofWare.Expect.Diff -> string
|
WoofWare.Expect.DiffModule.format [static method]: string WoofWare.Expect.Diff' -> string
|
||||||
WoofWare.Expect.DiffModule.formatWithLineNumbers [static method]: WoofWare.Expect.Diff -> string
|
WoofWare.Expect.DiffModule.format' [static method]: ('line -> string) -> 'line WoofWare.Expect.Diff' -> string
|
||||||
WoofWare.Expect.DiffModule.myers [static method]: string [] -> string [] -> WoofWare.Expect.Diff
|
WoofWare.Expect.DiffModule.formatWithLineNumbers [static method]: string WoofWare.Expect.Diff' -> string
|
||||||
WoofWare.Expect.DiffModule.patience [static method]: string -> string -> WoofWare.Expect.Diff
|
WoofWare.Expect.DiffModule.formatWithLineNumbers' [static method]: ('line -> string) -> 'line WoofWare.Expect.Diff' -> string
|
||||||
WoofWare.Expect.DiffModule.patienceLines [static method]: string [] -> string [] -> WoofWare.Expect.Diff
|
WoofWare.Expect.DiffModule.myers [static method]: string [] -> string [] -> string WoofWare.Expect.Diff'
|
||||||
WoofWare.Expect.DiffOperation inherit obj, implements WoofWare.Expect.DiffOperation System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Expect.DiffOperation System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 3 cases
|
WoofWare.Expect.DiffModule.patience [static method]: string -> string -> string WoofWare.Expect.Diff'
|
||||||
WoofWare.Expect.DiffOperation+Delete inherit WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffModule.patienceLines [static method]: 'line [] -> 'line [] -> 'line WoofWare.Expect.Diff'
|
||||||
WoofWare.Expect.DiffOperation+Delete.get_line [method]: unit -> string
|
WoofWare.Expect.DiffOperation`1 inherit obj, implements 'line WoofWare.Expect.DiffOperation System.IEquatable, System.Collections.IStructuralEquatable, 'line WoofWare.Expect.DiffOperation System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 3 cases
|
||||||
WoofWare.Expect.DiffOperation+Delete.get_posA [method]: unit -> int
|
WoofWare.Expect.DiffOperation`1+Delete inherit 'line WoofWare.Expect.DiffOperation
|
||||||
WoofWare.Expect.DiffOperation+Delete.line [property]: [read-only] string
|
WoofWare.Expect.DiffOperation`1+Delete.get_line [method]: unit -> 'line
|
||||||
WoofWare.Expect.DiffOperation+Delete.posA [property]: [read-only] int
|
WoofWare.Expect.DiffOperation`1+Delete.get_posA [method]: unit -> int
|
||||||
WoofWare.Expect.DiffOperation+Insert inherit WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffOperation`1+Delete.line [property]: [read-only] 'line
|
||||||
WoofWare.Expect.DiffOperation+Insert.get_line [method]: unit -> string
|
WoofWare.Expect.DiffOperation`1+Delete.posA [property]: [read-only] int
|
||||||
WoofWare.Expect.DiffOperation+Insert.get_posB [method]: unit -> int
|
WoofWare.Expect.DiffOperation`1+Insert inherit 'line WoofWare.Expect.DiffOperation
|
||||||
WoofWare.Expect.DiffOperation+Insert.line [property]: [read-only] string
|
WoofWare.Expect.DiffOperation`1+Insert.get_line [method]: unit -> 'line
|
||||||
WoofWare.Expect.DiffOperation+Insert.posB [property]: [read-only] int
|
WoofWare.Expect.DiffOperation`1+Insert.get_posB [method]: unit -> int
|
||||||
WoofWare.Expect.DiffOperation+Match inherit WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffOperation`1+Insert.line [property]: [read-only] 'line
|
||||||
WoofWare.Expect.DiffOperation+Match.get_line [method]: unit -> string
|
WoofWare.Expect.DiffOperation`1+Insert.posB [property]: [read-only] int
|
||||||
WoofWare.Expect.DiffOperation+Match.get_posA [method]: unit -> int
|
WoofWare.Expect.DiffOperation`1+Match inherit 'line WoofWare.Expect.DiffOperation
|
||||||
WoofWare.Expect.DiffOperation+Match.get_posB [method]: unit -> int
|
WoofWare.Expect.DiffOperation`1+Match.get_line [method]: unit -> 'line
|
||||||
WoofWare.Expect.DiffOperation+Match.line [property]: [read-only] string
|
WoofWare.Expect.DiffOperation`1+Match.get_posA [method]: unit -> int
|
||||||
WoofWare.Expect.DiffOperation+Match.posA [property]: [read-only] int
|
WoofWare.Expect.DiffOperation`1+Match.get_posB [method]: unit -> int
|
||||||
WoofWare.Expect.DiffOperation+Match.posB [property]: [read-only] int
|
WoofWare.Expect.DiffOperation`1+Match.line [property]: [read-only] 'line
|
||||||
WoofWare.Expect.DiffOperation+Tags inherit obj
|
WoofWare.Expect.DiffOperation`1+Match.posA [property]: [read-only] int
|
||||||
WoofWare.Expect.DiffOperation+Tags.Delete [static field]: int = 1
|
WoofWare.Expect.DiffOperation`1+Match.posB [property]: [read-only] int
|
||||||
WoofWare.Expect.DiffOperation+Tags.Insert [static field]: int = 2
|
WoofWare.Expect.DiffOperation`1+Tags inherit obj
|
||||||
WoofWare.Expect.DiffOperation+Tags.Match [static field]: int = 0
|
WoofWare.Expect.DiffOperation`1+Tags.Delete [static field]: int = 1
|
||||||
WoofWare.Expect.DiffOperation.Equals [method]: (WoofWare.Expect.DiffOperation, System.Collections.IEqualityComparer) -> bool
|
WoofWare.Expect.DiffOperation`1+Tags.Insert [static field]: int = 2
|
||||||
WoofWare.Expect.DiffOperation.get_IsDelete [method]: unit -> bool
|
WoofWare.Expect.DiffOperation`1+Tags.Match [static field]: int = 0
|
||||||
WoofWare.Expect.DiffOperation.get_IsInsert [method]: unit -> bool
|
WoofWare.Expect.DiffOperation`1.Equals [method]: ('line WoofWare.Expect.DiffOperation, System.Collections.IEqualityComparer) -> bool
|
||||||
WoofWare.Expect.DiffOperation.get_IsMatch [method]: unit -> bool
|
WoofWare.Expect.DiffOperation`1.get_IsDelete [method]: unit -> bool
|
||||||
WoofWare.Expect.DiffOperation.get_Tag [method]: unit -> int
|
WoofWare.Expect.DiffOperation`1.get_IsInsert [method]: unit -> bool
|
||||||
WoofWare.Expect.DiffOperation.IsDelete [property]: [read-only] bool
|
WoofWare.Expect.DiffOperation`1.get_IsMatch [method]: unit -> bool
|
||||||
WoofWare.Expect.DiffOperation.IsInsert [property]: [read-only] bool
|
WoofWare.Expect.DiffOperation`1.get_Tag [method]: unit -> int
|
||||||
WoofWare.Expect.DiffOperation.IsMatch [property]: [read-only] bool
|
WoofWare.Expect.DiffOperation`1.IsDelete [property]: [read-only] bool
|
||||||
WoofWare.Expect.DiffOperation.NewDelete [static method]: (int, string) -> WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffOperation`1.IsInsert [property]: [read-only] bool
|
||||||
WoofWare.Expect.DiffOperation.NewInsert [static method]: (int, string) -> WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffOperation`1.IsMatch [property]: [read-only] bool
|
||||||
WoofWare.Expect.DiffOperation.NewMatch [static method]: (int, int, string) -> WoofWare.Expect.DiffOperation
|
WoofWare.Expect.DiffOperation`1.NewDelete [static method]: (int, 'line) -> 'line WoofWare.Expect.DiffOperation
|
||||||
WoofWare.Expect.DiffOperation.Tag [property]: [read-only] int
|
WoofWare.Expect.DiffOperation`1.NewInsert [static method]: (int, 'line) -> 'line WoofWare.Expect.DiffOperation
|
||||||
|
WoofWare.Expect.DiffOperation`1.NewMatch [static method]: (int, int, 'line) -> 'line WoofWare.Expect.DiffOperation
|
||||||
|
WoofWare.Expect.DiffOperation`1.Tag [property]: [read-only] int
|
||||||
|
WoofWare.Expect.Dot inherit obj
|
||||||
|
WoofWare.Expect.Dot+IFileSystem - interface with 3 member(s)
|
||||||
|
WoofWare.Expect.Dot+IFileSystem.DeleteFile [method]: string -> unit
|
||||||
|
WoofWare.Expect.Dot+IFileSystem.GetTempFileName [method]: unit -> string
|
||||||
|
WoofWare.Expect.Dot+IFileSystem.WriteFile [method]: string -> string -> unit
|
||||||
|
WoofWare.Expect.Dot+IProcess`1 - interface with 5 member(s)
|
||||||
|
WoofWare.Expect.Dot+IProcess`1.Create [method]: string -> string -> #(IDisposable)
|
||||||
|
WoofWare.Expect.Dot+IProcess`1.ExitCode [method]: #(IDisposable) -> int
|
||||||
|
WoofWare.Expect.Dot+IProcess`1.ReadStandardOutput [method]: #(IDisposable) -> string
|
||||||
|
WoofWare.Expect.Dot+IProcess`1.Start [method]: #(IDisposable) -> bool
|
||||||
|
WoofWare.Expect.Dot+IProcess`1.WaitForExit [method]: #(IDisposable) -> unit
|
||||||
|
WoofWare.Expect.Dot.fileSystem [static property]: [read-only] WoofWare.Expect.Dot+IFileSystem
|
||||||
|
WoofWare.Expect.Dot.get_fileSystem [static method]: unit -> WoofWare.Expect.Dot+IFileSystem
|
||||||
|
WoofWare.Expect.Dot.get_process' [static method]: unit -> System.Diagnostics.Process WoofWare.Expect.Dot+IProcess
|
||||||
|
WoofWare.Expect.Dot.get_render [static method]: unit -> (string -> string)
|
||||||
|
WoofWare.Expect.Dot.process' [static property]: [read-only] System.Diagnostics.Process WoofWare.Expect.Dot+IProcess
|
||||||
|
WoofWare.Expect.Dot.render [static property]: [read-only] string -> string
|
||||||
|
WoofWare.Expect.Dot.render' [static method]: #(IDisposable) WoofWare.Expect.Dot+IProcess -> WoofWare.Expect.Dot+IFileSystem -> string -> string -> string
|
||||||
WoofWare.Expect.ExpectBuilder inherit obj
|
WoofWare.Expect.ExpectBuilder inherit obj
|
||||||
WoofWare.Expect.ExpectBuilder..ctor [constructor]: (string * int)
|
WoofWare.Expect.ExpectBuilder..ctor [constructor]: (string * int)
|
||||||
WoofWare.Expect.ExpectBuilder..ctor [constructor]: bool
|
WoofWare.Expect.ExpectBuilder..ctor [constructor]: bool
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
<Compile Include="Text.fs" />
|
<Compile Include="Text.fs" />
|
||||||
<Compile Include="File.fs" />
|
<Compile Include="File.fs" />
|
||||||
<Compile Include="Diff.fs" />
|
<Compile Include="Diff.fs" />
|
||||||
|
<Compile Include="Dot.fs" />
|
||||||
<Compile Include="Domain.fs" />
|
<Compile Include="Domain.fs" />
|
||||||
<Compile Include="SnapshotUpdate.fs" />
|
<Compile Include="SnapshotUpdate.fs" />
|
||||||
<Compile Include="Config.fs" />
|
<Compile Include="Config.fs" />
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.5",
|
"version": "0.7",
|
||||||
"publicReleaseRefSpec": [
|
"publicReleaseRefSpec": [
|
||||||
"^refs/heads/main$"
|
"^refs/heads/main$"
|
||||||
],
|
],
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
pkgs.nodePackages.markdown-link-check
|
pkgs.nodePackages.markdown-link-check
|
||||||
pkgs.shellcheck
|
pkgs.shellcheck
|
||||||
pkgs.xmlstarlet
|
pkgs.xmlstarlet
|
||||||
|
pkgs.graph-easy
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@@ -189,6 +189,11 @@
|
|||||||
"version": "4.2.13",
|
"version": "4.2.13",
|
||||||
"hash": "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg="
|
"hash": "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg="
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pname": "System.IO.Abstractions.TestingHelpers",
|
||||||
|
"version": "4.2.13",
|
||||||
|
"hash": "sha256-WGGatXlgyROnptdw0zU3ggf54eD/zusO/fvtf+5wuPU="
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pname": "System.IO.FileSystem.AccessControl",
|
"pname": "System.IO.FileSystem.AccessControl",
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
|
Reference in New Issue
Block a user