Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mbarbin committed Aug 22, 2024
1 parent b20a78d commit df17aef
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 0 deletions.
274 changes: 274 additions & 0 deletions test/expect/nonraising_unit_tests.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
(*******************************************************************************)
(* Vcs - a Versatile OCaml Library for Git Operations *)
(* Copyright (C) 2024 Mathieu Barbin <[email protected]> *)
(* *)
(* This file is part of Vcs. *)
(* *)
(* Vcs is free software; you can redistribute it and/or modify it under *)
(* the terms of the GNU Lesser General Public License as published by the *)
(* Free Software Foundation either version 3 of the License, or any later *)
(* version, with the LGPL-3.0 Linking Exception. *)
(* *)
(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *)
(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *)
(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *)
(* the file `NOTICE.md` at the root of this repository for more details. *)
(* *)
(* You should have received a copy of the GNU Lesser General Public License *)
(* and the LGPL-3.0 Linking Exception along with this library. If not, see *)
(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
(*******************************************************************************)

(* Cover once each function using the non-raising interface. *)

(* A utility to map the revisions to short and stable keys ("rev0", "rev1", etc). *)
let map_sexp =
let next = ref (-1) in
let revs = Hashtbl.create (module Vcs.Rev) in
let redact rev =
match Hashtbl.find revs rev with
| Some redacted -> redacted
| None ->
let redacted =
Int.incr next;
let n = !next in
Printf.sprintf "rev%d" n
in
Hashtbl.set revs ~key:rev ~data:redacted;
redacted
in
let rec aux sexp : Sexp.t =
match (sexp : Sexp.t) with
| List sexps -> List (List.map sexps ~f:aux)
| Atom rev ->
(match Vcs.Rev.of_string rev with
| Error _ -> sexp
| Ok rev -> Atom (redact rev))
in
aux
;;

let%expect_test "num stat without lines" =
Eio_main.run
@@ fun env ->
Eio.Switch.run
@@ fun sw ->
let vcs = Vcs_git.create ~env in
let mock_revs = Vcs.Mock_revs.create () in
let repo_root = Vcs_test_helpers.init_temp_repo ~env ~sw ~vcs in
let () =
match
Vcs.Or_error.add vcs ~repo_root ~path:(Vcs.Path_in_repo.v "unknown-file.txt")
with
| Ok () -> assert false
| Error e ->
print_s
(Vcs_test_helpers.redact_sexp
(e |> Error.sexp_of_t)
~fields:[ "cwd"; "repo_root" ])
in
[%expect
{|
((steps ((
Vcs.add (
(repo_root <REDACTED>)
(path unknown-file.txt)))))
(error (
(prog git)
(args (add unknown-file.txt))
(exit_status (Exited 128))
(cwd <REDACTED>)
(stdout "")
(stderr ("fatal: pathspec 'unknown-file.txt' did not match any files"))
(error "expected exit code 0"))))
|}];
let () =
match
Vcs.Or_error.commit
vcs
~repo_root
~commit_message:(Vcs.Commit_message.v "Nothing to commit")
with
| Ok (_ : Vcs.Rev.t) -> assert false
| Error e ->
print_s
(Vcs_test_helpers.redact_sexp
(e |> Error.sexp_of_t)
~fields:[ "cwd"; "repo_root"; "stdout" ])
in
[%expect
{|
((steps ((Vcs.commit ((repo_root <REDACTED>)))))
(error (
(prog git)
(args (commit -m "Nothing to commit"))
(exit_status (Exited 1))
(cwd <REDACTED>)
(stdout <REDACTED>)
(stderr "")
(error "expected exit code 0"))))
|}];
let commit_file ~path ~file_contents =
let result =
let%bind () =
Vcs.Or_error.save_file
vcs
~path:(Vcs.Repo_root.append repo_root path)
~file_contents:(Vcs.File_contents.create file_contents)
in
let%bind () = Vcs.Or_error.add vcs ~repo_root ~path in
Vcs.Or_error.commit vcs ~repo_root ~commit_message:(Vcs.Commit_message.v "_")
in
Or_error.ok_exn result
in
let hello_file = Vcs.Path_in_repo.v "hello.txt" in
let rev = commit_file ~path:hello_file ~file_contents:"Hello World!" in
let mock_rev = Vcs.Mock_revs.to_mock mock_revs ~rev in
print_s [%sexp (mock_rev : Vcs.Rev.t)];
[%expect {| 1185512b92d612b25613f2e5b473e5231185512b |}];
let result =
let%bind () =
Vcs.Or_error.rename_current_branch vcs ~repo_root ~to_:(Vcs.Branch_name.v "branch")
in
Vcs.Or_error.current_branch vcs ~repo_root
in
print_s [%sexp (result : Vcs.Branch_name.t Or_error.t)];
[%expect {| (Ok branch) |}];
Vcs.rename_current_branch vcs ~repo_root ~to_:Vcs.Branch_name.main;
let result =
let%map rev = Vcs.Or_error.current_revision vcs ~repo_root in
Vcs.Mock_revs.to_mock mock_revs ~rev
in
print_s [%sexp (result : Vcs.Rev.t Or_error.t)];
[%expect {| (Ok 1185512b92d612b25613f2e5b473e5231185512b) |}];
let result = Vcs.Or_error.current_branch vcs ~repo_root in
print_s [%sexp (result : Vcs.Branch_name.t Or_error.t)];
[%expect {| (Ok main) |}];
let show_file_at_rev ~rev ~path =
Vcs.Or_error.show_file_at_rev vcs ~repo_root ~rev ~path
in
let result = show_file_at_rev ~rev ~path:hello_file in
print_s [%sexp (result : [ `Present of Vcs.File_contents.t | `Absent ] Or_error.t)];
[%expect {| (Ok (Present "Hello World!")) |}];
let result = show_file_at_rev ~rev ~path:(Vcs.Path_in_repo.v "absent-file.txt") in
print_s [%sexp (result : [ `Present of Vcs.File_contents.t | `Absent ] Or_error.t)];
[%expect {| (Ok Absent) |}];
let result =
(* We've characterized here that Git does not distinguish between a file
absent at a valid revision, and an unknown revision. *)
show_file_at_rev
~rev:(Vcs.Mock_revs.next mock_revs)
~path:(Vcs.Path_in_repo.v "absent-file.txt")
in
print_s [%sexp (result : [ `Present of Vcs.File_contents.t | `Absent ] Or_error.t)];
[%expect {| (Ok Absent) |}];
let result =
Vcs.Or_error.load_file vcs ~path:(Vcs.Repo_root.append repo_root hello_file)
in
print_s [%sexp (result : Vcs.File_contents.t Or_error.t)];
[%expect {| (Ok "Hello World!") |}];
let result = Vcs.Or_error.ls_files vcs ~repo_root ~below:Vcs.Path_in_repo.root in
print_s [%sexp (result : Vcs.Path_in_repo.t list Or_error.t)];
[%expect {| (Ok (hello.txt)) |}];
let () =
(* Below must be an existing directory or [ls_files] returns an error. *)
match Vcs.Or_error.ls_files vcs ~repo_root ~below:(Vcs.Path_in_repo.v "dir") with
| Ok _ -> assert false
| Error e ->
print_s
(Vcs_test_helpers.redact_sexp
(e |> Error.sexp_of_t)
~fields:[ "cwd"; "error"; "repo_root" ])
in
[%expect
{|
((steps ((
Vcs.ls_files (
(repo_root <REDACTED>)
(below dir)))))
(error <REDACTED>))
|}];
let foo_file = Vcs.Path_in_repo.v "foo.txt" in
let rev2 = commit_file ~path:foo_file ~file_contents:"Hello Foo!" in
let bar_file = Vcs.Path_in_repo.v "bar.txt" in
let rev3 = commit_file ~path:bar_file ~file_contents:"Hello Bar!" in
let rev4 = commit_file ~path:bar_file ~file_contents:"Hello Again Bar!" in
let result =
Vcs.Or_error.name_status vcs ~repo_root ~changed:(Between { src = rev2; dst = rev3 })
in
print_s [%sexp (result : Vcs.Name_status.t Or_error.t)];
[%expect {| (Ok ((Added bar.txt))) |}];
let result =
Vcs.Or_error.name_status vcs ~repo_root ~changed:(Between { src = rev3; dst = rev4 })
in
print_s [%sexp (result : Vcs.Name_status.t Or_error.t)];
[%expect {| (Ok ((Modified bar.txt))) |}];
let result =
Vcs.Or_error.num_status vcs ~repo_root ~changed:(Between { src = rev2; dst = rev3 })
in
print_s [%sexp (result : Vcs.Num_status.t Or_error.t)];
[%expect
{|
(Ok ((
(key (One_file bar.txt))
(num_stat (
Num_lines_in_diff (
(insertions 1)
(deletions 0)))))))
|}];
let result =
Vcs.Or_error.num_status vcs ~repo_root ~changed:(Between { src = rev3; dst = rev4 })
in
print_s [%sexp (result : Vcs.Num_status.t Or_error.t)];
[%expect
{|
(Ok ((
(key (One_file bar.txt))
(num_stat (
Num_lines_in_diff (
(insertions 1)
(deletions 1)))))))
|}];
let () =
match Vcs.Or_error.log vcs ~repo_root with
| Error _ -> assert false
| Ok log ->
(* We traverse the log in reverse order first to assign revisions bottom
up (this makes it more readable). *)
ignore (map_sexp [%sexp (List.rev log : Vcs.Log.t)] : Sexp.t);
print_s (map_sexp [%sexp (log : Vcs.Log.t)])
in
[%expect
{|
((Commit (rev rev3) (parent rev2))
(Commit (rev rev2) (parent rev1))
(Commit (rev rev1) (parent rev0))
(Root (rev rev0)))
|}];
let () =
match Vcs.Or_error.refs vcs ~repo_root with
| Error _ -> assert false
| Ok refs -> print_s (map_sexp [%sexp (refs : Vcs.Refs.t)])
in
[%expect {| (((rev rev3) (ref_kind (Local_branch (branch_name main))))) |}];
let () =
match Vcs.Or_error.tree vcs ~repo_root with
| Error _ -> assert false
| Ok tree -> print_s (map_sexp [%sexp (tree : Vcs.Tree.t)])
in
[%expect
{|
((nodes (
(#3 (Commit (rev rev3) (parent #2)))
(#2 (Commit (rev rev2) (parent #1)))
(#1 (Commit (rev rev1) (parent #0)))
(#0 (Root (rev rev0)))))
(revs (
(#3 rev3)
(#2 rev2)
(#1 rev1)
(#0 rev0)))
(refs ((#3 ((Local_branch (branch_name main)))))))
|}];
()
;;
20 changes: 20 additions & 0 deletions test/expect/nonraising_unit_tests.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(*_******************************************************************************)
(*_ Vcs - a Versatile OCaml Library for Git Operations *)
(*_ Copyright (C) 2024 Mathieu Barbin <[email protected]> *)
(*_ *)
(*_ This file is part of Vcs. *)
(*_ *)
(*_ Vcs is free software; you can redistribute it and/or modify it under *)
(*_ the terms of the GNU Lesser General Public License as published by the *)
(*_ Free Software Foundation either version 3 of the License, or any later *)
(*_ version, with the LGPL-3.0 Linking Exception. *)
(*_ *)
(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *)
(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *)
(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *)
(*_ the file `NOTICE.md` at the root of this repository for more details. *)
(*_ *)
(*_ You should have received a copy of the GNU Lesser General Public License *)
(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *)
(*_ <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
(*_******************************************************************************)
22 changes: 22 additions & 0 deletions test/expect/raising_unit_tests.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(*******************************************************************************)
(* Vcs - a Versatile OCaml Library for Git Operations *)
(* Copyright (C) 2024 Mathieu Barbin <[email protected]> *)
(* *)
(* This file is part of Vcs. *)
(* *)
(* Vcs is free software; you can redistribute it and/or modify it under *)
(* the terms of the GNU Lesser General Public License as published by the *)
(* Free Software Foundation either version 3 of the License, or any later *)
(* version, with the LGPL-3.0 Linking Exception. *)
(* *)
(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *)
(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *)
(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *)
(* the file `NOTICE.md` at the root of this repository for more details. *)
(* *)
(* You should have received a copy of the GNU Lesser General Public License *)
(* and the LGPL-3.0 Linking Exception along with this library. If not, see *)
(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
(*******************************************************************************)

(* Cover once each function using the raising interface. *)
20 changes: 20 additions & 0 deletions test/expect/raising_unit_tests.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(*_******************************************************************************)
(*_ Vcs - a Versatile OCaml Library for Git Operations *)
(*_ Copyright (C) 2024 Mathieu Barbin <[email protected]> *)
(*_ *)
(*_ This file is part of Vcs. *)
(*_ *)
(*_ Vcs is free software; you can redistribute it and/or modify it under *)
(*_ the terms of the GNU Lesser General Public License as published by the *)
(*_ Free Software Foundation either version 3 of the License, or any later *)
(*_ version, with the LGPL-3.0 Linking Exception. *)
(*_ *)
(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *)
(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *)
(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *)
(*_ the file `NOTICE.md` at the root of this repository for more details. *)
(*_ *)
(*_ You should have received a copy of the GNU Lesser General Public License *)
(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *)
(*_ <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
(*_******************************************************************************)

0 comments on commit df17aef

Please sign in to comment.