ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
165
scripts/hooks/hook-tests.fsx
Normal file
165
scripts/hooks/hook-tests.fsx
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
open System
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
|
||||
type Result = { Code: int; Output: string; Error: string }
|
||||
type Fixture = { Root: string; Source: string; Mask: string }
|
||||
|
||||
let require condition message =
|
||||
if not condition then invalidOp message
|
||||
|
||||
let run root environment executable arguments =
|
||||
let start = ProcessStartInfo executable
|
||||
start.WorkingDirectory <- root
|
||||
start.UseShellExecute <- false
|
||||
start.RedirectStandardOutput <- true
|
||||
start.RedirectStandardError <- true
|
||||
for argument in arguments do start.ArgumentList.Add argument
|
||||
for name, value in environment do start.Environment[name] <- value
|
||||
use child = Process.Start start
|
||||
let output = child.StandardOutput.ReadToEndAsync()
|
||||
let error = child.StandardError.ReadToEndAsync()
|
||||
child.WaitForExit()
|
||||
{ Code = child.ExitCode; Output = output.Result; Error = error.Result }
|
||||
|
||||
let git fixture arguments =
|
||||
let result = run fixture.Root [] "git" arguments
|
||||
require (result.Code = 0) result.Error
|
||||
result.Output
|
||||
|
||||
let write path (text: string) = File.WriteAllText(path, text)
|
||||
let stage fixture = git fixture [ "add"; "." ] |> ignore
|
||||
let hook = Path.Combine(__SOURCE_DIRECTORY__, "pre-commit")
|
||||
|
||||
let runHook fixture environment =
|
||||
let before = git fixture [ "ls-files"; "--stage"; "-z" ]
|
||||
let result = run fixture.Root environment hook []
|
||||
require (before = git fixture [ "ls-files"; "--stage"; "-z" ]) "hook changed the index"
|
||||
result
|
||||
|
||||
let passes fixture =
|
||||
let result = runHook fixture []
|
||||
require (result.Code = 0) result.Error
|
||||
|
||||
let fails expected fixture =
|
||||
let result = runHook fixture []
|
||||
require (result.Code <> 0) "hook unexpectedly succeeded"
|
||||
require (result.Error.Contains(expected: string)) result.Error
|
||||
|
||||
let directory fixture path = Directory.CreateDirectory(Path.Combine(fixture.Root, path)).FullName
|
||||
|
||||
let tests: (string * (Fixture -> unit)) list =
|
||||
[ "staged tree", fun fixture ->
|
||||
write fixture.Source "unstaged source edit\n"
|
||||
write fixture.Mask "unstaged invalid mask\n"
|
||||
passes fixture
|
||||
|
||||
"unrelated change", fun fixture ->
|
||||
write fixture.Source "other=changed\nvalue=synthetic\n"
|
||||
stage fixture
|
||||
passes fixture
|
||||
|
||||
"missing match", fun fixture ->
|
||||
write fixture.Source "value=changed\n"
|
||||
stage fixture
|
||||
fails "no match" fixture
|
||||
|
||||
"multiple matches", fun fixture ->
|
||||
write fixture.Source "synthetic synthetic\n"
|
||||
stage fixture
|
||||
fails "multiple matches" fixture
|
||||
|
||||
"overlapping matches", fun fixture ->
|
||||
write fixture.Source "aaa"
|
||||
write fixture.Mask "[[replace]]\nbefore = 'aa'\nafter = 'b'\n"
|
||||
stage fixture
|
||||
fails "multiple matches" fixture
|
||||
|
||||
"empty before", fun fixture ->
|
||||
write fixture.Mask "[[replace]]\nbefore = ''\nafter = 'x'\n"
|
||||
stage fixture
|
||||
fails "before is empty" fixture
|
||||
|
||||
"ordered rules", fun fixture ->
|
||||
write fixture.Mask
|
||||
("[[replace]]\nbefore = 'synthetic'\nafter = 'intermediate'\n"
|
||||
+ "[[replace]]\nbefore = 'intermediate'\nafter = '********'\n")
|
||||
stage fixture
|
||||
passes fixture
|
||||
|
||||
"invalid TOML", fun fixture ->
|
||||
write fixture.Mask "invalid = ["
|
||||
stage fixture
|
||||
let result = runHook fixture []
|
||||
require (result.Code <> 0) "invalid TOML was accepted"
|
||||
|
||||
"invalid schema", fun fixture ->
|
||||
write fixture.Mask "[[replace]]\nbefore = 'synthetic'\nafter = 1\n"
|
||||
stage fixture
|
||||
fails "expected text" fixture
|
||||
|
||||
"missing target", fun fixture ->
|
||||
git fixture [ "rm"; "--cached"; "config.txt" ] |> ignore
|
||||
fails "target is not a regular file" fixture
|
||||
|
||||
"symlink target", fun fixture ->
|
||||
File.Delete fixture.Source
|
||||
File.CreateSymbolicLink(fixture.Source, "elsewhere") |> ignore
|
||||
stage fixture
|
||||
fails "target is not a regular file" fixture
|
||||
|
||||
"omitted subtree", fun fixture ->
|
||||
let hidden = directory fixture "hidden"
|
||||
write (Path.Combine(hidden, ".omit")) ""
|
||||
write (Path.Combine(hidden, "invalid.mask.toml")) "invalid"
|
||||
let nested = directory fixture "hidden/nested"
|
||||
write (Path.Combine(nested, ".omit")) ""
|
||||
write (Path.Combine(nested, "legacy.mask.diff")) "invalid"
|
||||
stage fixture
|
||||
let result = runHook fixture []
|
||||
require (result.Code = 0) result.Error
|
||||
require (result.Output.Contains "1 directories omitted") result.Output
|
||||
|
||||
"omit prefix boundary", fun fixture ->
|
||||
let hidden = directory fixture "hidden"
|
||||
write (Path.Combine(hidden, ".omit")) ""
|
||||
let peer = directory fixture "hidden-peer"
|
||||
write (Path.Combine(peer, "invalid.mask.toml")) "invalid"
|
||||
stage fixture
|
||||
fails "target is not a regular file" fixture
|
||||
|
||||
"unstaged omit", fun fixture ->
|
||||
write fixture.Source "synthetic synthetic"
|
||||
stage fixture
|
||||
write (Path.Combine(fixture.Root, ".omit")) ""
|
||||
fails "multiple matches" fixture
|
||||
|
||||
"legacy format", fun fixture ->
|
||||
write (Path.Combine(fixture.Root, "old.mask.diff")) "invalid"
|
||||
stage fixture
|
||||
fails "legacy mask format" fixture
|
||||
|
||||
"alternate index", fun fixture ->
|
||||
let index = Path.Combine(fixture.Root, "alternate")
|
||||
File.Copy(Path.Combine(fixture.Root, ".git/index"), index)
|
||||
write fixture.Source "staged drift\n"
|
||||
git fixture [ "add"; "config.txt" ] |> ignore
|
||||
let before = File.ReadAllBytes index
|
||||
let result = runHook fixture [ "GIT_INDEX_FILE", index ]
|
||||
require (result.Code = 0) result.Error
|
||||
require (before = File.ReadAllBytes index) "hook changed the alternate index" ]
|
||||
|
||||
for name, test in tests do
|
||||
let root = Directory.CreateDirectory(Path.Combine(fsi.CommandLineArgs[1], $"hook-tests-{Guid.NewGuid():N}")).FullName
|
||||
let fixture = { Root = root; Source = Path.Combine(root, "config.txt"); Mask = Path.Combine(root, "config.txt.mask.toml") }
|
||||
try
|
||||
git fixture [ "init"; "-q" ] |> ignore
|
||||
write fixture.Source "value=synthetic\n"
|
||||
write fixture.Mask "[[replace]]\nbefore = 'synthetic'\nafter = '********'\n"
|
||||
stage fixture
|
||||
test fixture
|
||||
printfn "passed: %s" name
|
||||
finally
|
||||
Directory.Delete(root, true)
|
||||
|
||||
printfn "%d hook tests passed" tests.Length
|
||||
Loading…
Reference in a new issue