(defmodule lamina_fossil_tests
(export all)
(include-lib "eunit/include/eunit.hrl"))
(defun run-bin-captures-output-and-status_test ()
(case (lamina_fossil:run-bin "/bin/sh"
(list "-c" "printf out; printf err >&2; exit 7")
1000)
(`#(error #(exit_status 7 ,output))
(if (=:= "outerr" output)
'ok
(erlang:error (list "unexpected output" output))))
(other (erlang:error (list "unexpected result" other)))))
(defun run-bin-times-out_test ()
(case (lamina_fossil:run-bin "/bin/sh" (list "-c" "sleep 2") 30)
(`#(error timeout) 'ok)
(other (erlang:error (list "timeout was not reported" other)))))
(defun run-bin-classifies-missing-executable_test ()
(case (lamina_fossil:run-bin "/definitely/missing/lamina-fossil" '() 1000)
(`#(error #(enoent ,_)) 'ok)
(other (erlang:error (list "missing executable was not classified" other)))))
(defun fossil-init-and-description_test ()
(let* ((dir (tmpdir))
(path (filename:join dir "demo.fossil")))
(case (lamina_fossil_repo:init path "admin")
(`#(ok ,_)
(case (lamina_fossil_repo:set-user-pw path "admin" "s3cret!")
(`#(ok ,_)
(case (lamina_fossil_repo:set-description path "demo" "hello ' world")
(`#(ok ,_)
(let ((rows (lamina_fossil:run
(list "sql" "-R" path
"SELECT name,value FROM config WHERE name LIKE 'project-%' ORDER BY name;"))))
(cleanup dir)
(case rows
(`#(ok ,output)
(if (and (lists:member "project-description|hello ' world" (string:split output "\n" 'all))
(lists:member "project-name|demo" (string:split output "\n" 'all)))
'ok
(erlang:error (list "description not persisted" output))))
(other (erlang:error (list "query failed" other))))))
(other (cleanup dir) (erlang:error (list "description command failed" other)))))
(other (cleanup dir) (erlang:error (list "password command failed" other)))))
(other (cleanup dir) (erlang:error (list "init command failed" other))))))
(defun parse-timeline-output-reads-sql-and-cli_test ()
(let ((sql (lamina_fossil_repo:parse-timeline-output "2026-09-12 13:49\n"))
(cli (lamina_fossil_repo:parse-timeline-output
"=== 2026-09-12 ===\n05:49:44 [e170b276b4] initial empty check-in\n")))
(if (and (=:= "2026-09-12 13:49" sql)
(=:= "2026-09-12 05:49:44" cli))
'ok
(erlang:error (list "timeline parse failed" sql cli)))))
(defun cleanup (dir)
(catch (file:del_dir_r dir))
'ok)
(defun tmpdir ()
(let* ((cwd (element 2 (file:get_cwd)))
(base (filename:join cwd "_build/tmp"))
(name (lists:flatten (io_lib:format "fossil-~p" (list (os:system_time 'microsecond))))))
(filelib:ensure_dir (filename:join base "x"))
(let ((dir (filename:join base name)))
(file:make_dir dir)
dir)))