aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/tests/test_refs.py
diff options
context:
space:
mode:
authorgodosa <godosa@godosa.eu>2026-10-07 07:27:17 +0200
committergodosa <godosa@godosa.eu>2026-10-07 07:27:17 +0200
commit81d4e80fd5aabe4e80f58e960affa795cf7d34ec (patch)
treee98eeac2af6af63aa4287bba1f6d4a3af26b5727 /tests/test_refs.py
downloadworkflow-81d4e80fd5aabe4e80f58e960affa795cf7d34ec.tar.gz
workflow-81d4e80fd5aabe4e80f58e960affa795cf7d34ec.zip
workflow: initial public history
Diffstat (limited to 'tests/test_refs.py')
-rw-r--r--tests/test_refs.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/test_refs.py b/tests/test_refs.py
new file mode 100644
index 0000000..4242a03
--- /dev/null
+++ b/tests/test_refs.py
@@ -0,0 +1,109 @@
+import sys
+import tempfile
+import unittest
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
+from wflib import refs as R
+
+DOC = """\
+# Design
+
+Intro.
+
+## Subsystems
+
+### Character Model
+
+Bones and poses.
+
+#### Detail
+
+Deep.
+
+<a id="terrain"></a>
+### Terrain & caves!
+
+Heightmap.
+
+## Other
+
+<a id="loose"></a>
+Loose paragraph anchor.
+"""
+
+
+class LinksTest(unittest.TestCase):
+ def test_links(self):
+ self.assertEqual(R.links("see [[t-a]] and [[a-b|label]] and [[doc#part]]"), ["t-a", "a-b", "doc"])
+
+ def test_code_is_skipped(self):
+ self.assertEqual(R.links("`[[t-x]]` then [[t-y]]\n```\n[[t-z]]\n```\n"), ["t-y"])
+
+
+class SectionsTest(unittest.TestCase):
+ def test_slugify(self):
+ self.assertEqual(R.slugify("Character Model"), "character-model")
+ self.assertEqual(R.slugify("Terrain & caves!"), "terrain-caves")
+
+ def test_sections(self):
+ got = [(s.level, s.heading, sorted(s.anchors), s.start, s.end) for s in R.sections(DOC)]
+ self.assertEqual(got, [
+ (1, "Design", ["design"], 0, 23),
+ (2, "Subsystems", ["subsystems"], 4, 19),
+ (3, "Character Model", ["character-model"], 6, 14),
+ (4, "Detail", ["detail"], 10, 14),
+ (3, "Terrain & caves!", ["terrain", "terrain-caves"], 15, 19),
+ (2, "Other", ["other"], 19, 23),
+ (0, "", ["loose"], 21, 23),
+ ])
+
+ def test_anchors(self):
+ self.assertEqual(R.anchors(DOC), {"design", "subsystems", "character-model", "detail",
+ "terrain", "terrain-caves", "other", "loose"})
+
+ def test_headings_in_code_fences_are_not_sections(self):
+ self.assertEqual(R.anchors("# A\n```\n# not a heading\n```\n"), {"a"})
+
+
+class ResolveTest(unittest.TestCase):
+ def setUp(self):
+ self.tmp = tempfile.TemporaryDirectory()
+ self.root = Path(self.tmp.name)
+ (self.root / "docs").mkdir()
+ (self.root / "DESIGN.md").write_text(DOC)
+ long = "# Long\n\n## Part\n" + "".join(f"line {n}\n" for n in range(1, 100))
+ (self.root / "docs" / "x.md").write_text(long)
+ (self.root / "docs" / "plan.md").write_text("# The Plan\n\n**Goal:** Ship it.\n\nMore.\n")
+
+ def tearDown(self):
+ self.tmp.cleanup()
+
+ def test_anchor_section(self):
+ self.assertEqual(R.resolve(self.root, "DESIGN.md", "terrain"),
+ "===== DESIGN.md#terrain (line 16) =====\n### Terrain & caves!\n\nHeightmap.")
+
+ def test_long_section_is_cut(self):
+ out = R.resolve(self.root, "docs/x.md", "part").split("\n")
+ self.assertEqual(out[0], "===== docs/x.md#part (line 3) =====")
+ self.assertEqual(out[1], "## Part")
+ self.assertEqual(out[80], "line 79")
+ self.assertEqual(out[81], "… (20 more lines: docs/x.md:83)")
+ self.assertEqual(len(out), 82)
+
+ def test_missing_anchor(self):
+ self.assertEqual(R.resolve(self.root, "DESIGN.md", "nope"), "(no anchor 'nope' in DESIGN.md)")
+
+ def test_missing_file(self):
+ self.assertEqual(R.resolve(self.root, "docs/none.md", None), "(missing: docs/none.md)")
+
+ def test_path_only_gives_heading_and_goal(self):
+ self.assertEqual(R.resolve(self.root, "docs/plan.md", None), "docs/plan.md: The Plan — Ship it.")
+ self.assertEqual(R.resolve(self.root, "DESIGN.md", None), "DESIGN.md: Design")
+
+ def test_directory(self):
+ self.assertEqual(R.resolve(self.root, "docs", None), "docs/ (directory)")
+
+
+if __name__ == "__main__":
+ unittest.main()