simple-learning

Simple learning web program
git clone git://git.laack.co/simple-learning.git
Log | Files | Refs | README | LICENSE

commit 7835c21a2e54612e597c3a75e86ab36353621129
parent e43319905105548d91102e98c5926df838e05dcb
Author: Andrew Laack <andrew@laack.co>
Date:   Tue,  1 Sep 2026 19:59:40 -0500

Setup basic testing for rendering

Diffstat:
Alearning/Makefile | 4++++
Dlearning/dune.lock/kdf.1.1.0.pkg | 19-------------------
Alearning/dune.lock/kdf.1.1.1.pkg | 19+++++++++++++++++++
Mlearning/dune.lock/lock.dune | 2+-
Mlearning/lib/shared.ml | 3++-
Mlearning/test/dune | 4+++-
Alearning/test/test_courses/course_0/0_example.sl | 4++++
Alearning/test/test_courses/course_0/1_example.sl | 10++++++++++
Alearning/test/test_courses/course_0/hidden.md | 1+
Mlearning/test/test_learning.ml | 1+
Mlearning/test/test_rendering.ml | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
11 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/learning/Makefile b/learning/Makefile @@ -0,0 +1,4 @@ +run: + dune exec learning ../courses +tests: + dune runtest diff --git a/learning/dune.lock/kdf.1.1.0.pkg b/learning/dune.lock/kdf.1.1.0.pkg @@ -1,19 +0,0 @@ -(version 1.1.0) - -(build - (all_platforms - ((action - (progn - (when %{pkg-self:dev} (run dune subst)) - (run dune build -p %{pkg-self:name} -j %{jobs})))))) - -(depends - (all_platforms - (ocaml dune digestif mirage-crypto))) - -(source - (fetch - (url - https://github.com/robur-coop/kdf/releases/download/v1.1.0/kdf-1.1.0.tbz) - (checksum - sha512=85a8e95389be1040fa1ac76dc49a87d205366b5220f5c023d5ec3e72d5c193a9379dfd920027b9b58aee227300a4c558763380f607cc6558497352c13a82ed15))) diff --git a/learning/dune.lock/kdf.1.1.1.pkg b/learning/dune.lock/kdf.1.1.1.pkg @@ -0,0 +1,19 @@ +(version 1.1.1) + +(build + (all_platforms + ((action + (progn + (when %{pkg-self:dev} (run dune subst)) + (run dune build -p %{pkg-self:name} -j %{jobs})))))) + +(depends + (all_platforms + (ocaml dune digestif mirage-crypto))) + +(source + (fetch + (url + https://github.com/robur-coop/kdf/releases/download/v1.1.1/kdf-1.1.1.tbz) + (checksum + sha512=8584c24b249d9d264fc58e1cd8299968b6098fe915fe7c8f935937c7e3cb200bde0bd0fdb042fb000337fb0b6298866068933cd20b95e51a021cbf3e9e3c6456))) diff --git a/learning/dune.lock/lock.dune b/learning/dune.lock/lock.dune @@ -12,7 +12,7 @@ ((source https://github.com/ocaml-dune/opam-repository-relocatable.git#d64df82c7e16de819a770cabf4066a06243ed80b)) ((source - https://github.com/ocaml/opam-repository.git#faef8a99e98446bcc68159b6b5a4d5c00c816dfc)))) + https://github.com/ocaml/opam-repository.git#da8b7e6fa7491ffc5dc8eee7f8f60452a1b26ce7)))) (expanded_solver_variable_bindings (variable_values diff --git a/learning/lib/shared.ml b/learning/lib/shared.ml @@ -1 +1,2 @@ -let course_dir = if Array.length Sys.argv > 1 then Sys.argv.(1) ^ "/" else "../courses/" +(* ALWAYS pass in directory to watch. Fallback should only be for tests. *) +let course_dir = if Array.length Sys.argv > 1 then Sys.argv.(1) ^ "/" else "./test_courses/" diff --git a/learning/test/dune b/learning/test/dune @@ -1,3 +1,5 @@ (test (name test_learning) - (libraries learning)) + (libraries learning) + (deps (glob_files_rec ./test_courses/*)) + ) diff --git a/learning/test/test_courses/course_0/0_example.sl b/learning/test/test_courses/course_0/0_example.sl @@ -0,0 +1,4 @@ +# H +## H +### H +This is an example sl file. diff --git a/learning/test/test_courses/course_0/1_example.sl b/learning/test/test_courses/course_0/1_example.sl @@ -0,0 +1,10 @@ +#TEST +##TEST +##TEST +###TEST +=>TEST +=>eTEST +```TEST +??TEST +>TEST +*TEST diff --git a/learning/test/test_courses/course_0/hidden.md b/learning/test/test_courses/course_0/hidden.md @@ -0,0 +1 @@ +This is a hidden file... diff --git a/learning/test/test_learning.ml b/learning/test/test_learning.ml @@ -1 +1,2 @@ let () = Test_line_parsing.test_line_parsing () +let () = Test_rendering.test_rendering () diff --git a/learning/test/test_rendering.ml b/learning/test/test_rendering.ml @@ -1,4 +1,76 @@ open Learning +let courses = Array.to_list (Render.get_course_array) +let expected_courses = ["course_0";"course_1";"course_empty"] +let course_0_page_0 = Render.render_page "course_0" "0_example.sl" +let course_0_page_1 = Render.render_page "course_0" "1_example.sl" +let pages_in_order = Render.get_pages_in_order "course_0" + + +let contains s1 s2 = + let len1 = String.length s1 and len2 = String.length s2 in + let rec go idx = + if idx + len2 > len1 then false + else if String.sub s1 idx len2 = s2 then true + else go (idx + 1) + in + go 0 + + let test_rendering () = - print_endline (Render.get_path_to_page "smt" "smt") + + (* Verify non-sl extension pages are hidden for course listings. *) + assert ((List.length pages_in_order) = 2); + + (*Verify happy path course listing.*) + assert (courses = expected_courses); + assert ((Render.render_page "course_0" "0_example.sl") != ""); + + (* + Verify sensible expectations about each line. We assume the + mapping between sl headers and html headers, and then check + text existence. + *) + + assert (contains course_0_page_0 "<h1>"); + assert (contains course_0_page_0 "<h2>"); + assert (contains course_0_page_0 "<h3>"); + assert (contains course_0_page_0 "This is an example sl file."); + + (* + Verify the following don't render when mis-specified: + - # -> h1 + - ## -> h2 + - ### -> h3 + - => -> href + - =>e -> iframe + - ``` -> results in subsequent preformatted lines + - ?? -> summary (used to hide / unhide in html) + - > -> blockquote + - * -> ul + *) + + (* TODO: These are brittle; add classes for rendering / validation in templates. *) + assert (not (contains course_0_page_1 "<h1>")); + assert (not (contains course_0_page_1 "<h2>")); + assert (not (contains course_0_page_1 "<h3>")); + assert (not (contains course_0_page_1 "href=TEST")); + assert (not (contains course_0_page_1 "iframe")); + assert (not (contains course_0_page_1 "<pre-formatted>")); + assert (not (contains course_0_page_1 "summary")); + assert (not (contains course_0_page_1 "quote")); + assert (not (contains course_0_page_1 "ul")); + +(* + type line_format = + | Normal + | HeaderL1 + | HeaderL2 + | HeaderL3 + | Embedded + | Preformatted + | Hidden + | Quote + | Link + | ListItem +*)