Fosi Fossil Service
Small teams. Open source. Built on Fossil.

CaaS / Lamina

Unified Management for Fossil Repositories

Public | Owner: CaaS | Default branch: trunk | Last update: 2026-10-25 00:41

Artifact 71945172d2282ee74aabf4bc3919293108ad3d6d25391cfed9c6d37230e7d449:


(defmodule lamina_docs_tests
  (export all)
  (include-lib "eunit/include/eunit.hrl"))

(defun catalog-nests-folders-and-puts-root-files-first_test ()
  (let ((groups (lamina_docs:catalog
                 (list "Guide/Install/intro.md"
                       "readme.md"
                       "Guide/readme.md"
                       "Guide/Install/Advanced/deep.markdown"
                       ".hidden/skip.md"
                       "Guide/shot.png"
                       "notes.txt"))))
    (let ((labels (lists:map (lambda (group) (maps:get 'label group)) groups))
          (general (hd groups)))
      (if (and (=:= (list "General" "Guide" "Guide / Install" "Guide / Install / Advanced") labels)
               (=:= "readme.md" (maps:get 'filename (hd (maps:get 'articles general)))))
          'ok
          (erlang:error (list "catalog shape" labels groups))))))

(defun readme-and-index-sort-ahead-of-filenames_test ()
  (let ((groups (lamina_docs:catalog
                 (list "Guide/zeta.md" "Guide/index.md" "Guide/alpha.md" "Guide/README.md"))))
    (let ((names (lists:map (lambda (article) (maps:get 'filename article))
                            (maps:get 'articles (hd groups)))))
      (if (=:= (list "README.md" "index.md" "alpha.md" "zeta.md") names)
          'ok
          (erlang:error (list "article order" names))))))

(defun title-uses-h1-then-filename_test ()
  (let (((tuple h1 rest) (lamina_docs:split-title "my-post.md" "# Install the app\n\nHello\n"))
        ((tuple file body) (lamina_docs:split-title "my_post.md" "No heading\n")))
    (if (and (=:= "Install the app" h1)
             (=:= "\nHello\n" rest)
             (=:= "my post" file)
             (=:= "No heading\n" body))
        'ok
        (erlang:error (list "titles" h1 file)))))

(defun markdown-escapes-html-and-rewrites-links_test ()
  (let ((html (lamina_docs:render-markdown
               "Hello <script>\n\nSee [next](next.md#part) and ![shot](./shot.png).\n\n[web](https://example.com)\n"
               "Guide/Install")))
    (if (and (=:= 'true (contains? html "<p>Hello &lt;script&gt;</p>"))
             (=:= 'true (contains? html "href=\"/docs/Guide/Install/next#part\""))
             (=:= 'true (contains? html "src=\"/docs/Guide/Install/shot.png\""))
             (=:= 'true (contains? html "href=\"https://example.com\""))
             (=:= 'false (contains? html "<script>")))
        'ok
        (erlang:error (list "markdown" html)))))

(defun markdown-renders-lists-code-and-tables_test ()
  (let ((html (lamina_docs:render-markdown
               "## Steps\n\n- one\n  - nested\n\n```erl\nok.\n```\n\n| A | B |\n| --- | --- |\n| 1 | 2 |\n"
               "")))
    (if (and (=:= 'true (contains? html "<h2>Steps</h2>"))
             (=:= 'true (contains? html "<li>one<ul><li>nested</li></ul></li>"))
             (=:= 'true (contains? html "<code class=\"language-erl\">ok.</code>"))
             (=:= 'true (contains? html "<th>A</th>"))
             (=:= 'true (contains? html "<td>2</td>")))
        'ok
        (erlang:error (list "blocks" html)))))

(defun parent-link-does-not-escape-the-repository_test ()
  (let ((html (lamina_docs:render-markdown "[x](../../secret.md)" "Guide")))
    (if (=:= 'true (contains? html "href=\"#\""))
        'ok
        (erlang:error (list "escaped link" html)))))

(defun percent-encoded-path-decodes-to-unicode_test ()
  (let ((path (lamina_docs:decode-url-path "%E6%8C%87%E5%8D%97/%E5%BC%80%E5%A7%8B")))
    (if (=:= (list 25351 21335 47 24320 22987) path)
        'ok
        (erlang:error path))))

(defun unicode-article-url-is-percent-encoded_test ()
  (let* ((path (lists:append (list (list 25351 21335) "/" (list 24320 22987) ".md")))
         (url (lamina_docs:article-url path)))
    (if (=:= "/docs/%E6%8C%87%E5%8D%97/%E5%BC%80%E5%A7%8B" url)
        'ok
        (erlang:error url))))

(defun encode-html-keeps-utf8-bytes-and-codepoints_test ()
  (let* ((emdash (binary_to_list (unicode:characters_to_binary (list 8212))))
         (mixed (lists:append (list "lamina " emdash " " (list 24320 22987))))
         (bin (lamina_docs:encode-html mixed))
         (expected (unicode:characters_to_binary (list "lamina " 8212 " " 24320 22987))))
    (if (=:= expected bin)
        'ok
        (erlang:error bin))))

(defun doc-counts-ignore-assets-and-group-directories_test ()
  (let ((stats (lamina_docs:doc-counts
                (list "readme.md" "Guide/readme.md" "Guide/Install/intro.md"
                      "Guide/shot.png" "notes.txt"))))
    (if (and (=:= 3 (maps:get 'articles stats))
             (=:= 3 (maps:get 'categories stats)))
        'ok
        (erlang:error stats))))

(defun parse-count-reads-the-first-integer_test ()
  (if (and (=:= 2 (lamina_docs:parse-count "2\n"))
           (=:= 0 (lamina_docs:parse-count "none")))
      'ok
      (erlang:error 'count)))

(defun format-bytes-uses-binary-units_test ()
  (let ((zero (lamina_docs:format-bytes 0))
        (kb (lamina_docs:format-bytes 1024))
        (mb (lamina_docs:format-bytes 1048576)))
    (if (and (=:= "0 B" zero) (=:= "1.0 KB" kb) (=:= "1.0 MB" mb))
        'ok
        (erlang:error (list zero kb mb)))))

(defun contains? (text needle)
  (/= 'nomatch (string:find text needle)))

Clone

You can clone this repository with the following command:

fossil clone https://fosi.dev/CaaS/Lamina

Contribute

The best way to contribute is through e-mail. See the project documentation for more details.