Skip to content

Commit d3dc9c9

Browse files
authored
Add tests for tei2json module functionality
This file contains tests for the tei2json module, including sample TEI files, processing functions, and assertions for expected output.
1 parent 304ae65 commit d3dc9c9

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

‎tests/test_tei2json.py‎

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# tests/test_tei2json.py
2+
import json
3+
import tempfile
4+
from pathlib import Path
5+
import shutil
6+
import os
7+
import pytest
8+
from lxml import etree
9+
10+
# adjust import path depending on where you placed tei2json.py
11+
# This assumes tei2json.py is at /tei2json.py
12+
import sys
13+
repo_root = Path(__file__).resolve().parents[1]
14+
sys.path.insert(0, str(repo_root / ))
15+
16+
import tei2json # the module from your repo
17+
18+
SAMPLE_TMPL = """<?xml version="1.0" encoding="utf-8"?>
19+
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="en" xml:id="manuscript_{id}">
20+
<teiHeader>
21+
<fileDesc>
22+
<titleStmt>
23+
<title level="a" xml:lang="en">Sample Title {id}</title>
24+
<title xml:lang="syr">ܫܠܡ {id}</title>
25+
</titleStmt>
26+
<publicationStmt>
27+
<idno type="URI">https://bl.syriac.uk/ms/{id}</idno>
28+
</publicationStmt>
29+
</fileDesc>
30+
</teiHeader>
31+
<text>
32+
<body>
33+
<p>body</p>
34+
</body>
35+
</text>
36+
<msDesc>
37+
<msIdentifier>
38+
<altIdentifier>
39+
<idno type="BL-Shelfmark">Add. {id}</idno>
40+
</altIdentifier>
41+
</msIdentifier>
42+
<msPart>
43+
<msContents>
44+
<msItem>
45+
<title xml:lang="en">Part title {id}</title>
46+
<finalRubric xml:lang="syr">ܪܘܒܪܝܩ {id}</finalRubric>
47+
<colophon>Colophon {id}</colophon>
48+
<persName>Person {id}</persName>
49+
<placeName>Place {id}</placeName>
50+
</msItem>
51+
</msContents>
52+
</msPart>
53+
</msDesc>
54+
</TEI>
55+
"""
56+
57+
# These tests cover 5 sample files;
58+
59+
def write_sample(dirpath: Path, idx: int) -> Path:
60+
p = dirpath / f"{idx}.xml"
61+
p.write_text(SAMPLE_TMPL.format(id=idx), encoding="utf8")
62+
return p
63+
64+
65+
@pytest.fixture(scope="module")
66+
def sample_dir(tmp_path_factory):
67+
d = tmp_path_factory.mktemp("tei_samples")
68+
# write 5 sample files (1..5)
69+
for i in range(1, 6):
70+
write_sample(d, i)
71+
return d
72+
73+
74+
def test_process_single_file(tmp_path):
75+
# Sanity check: process one file and assert keys present
76+
xml = tmp_path / "one.xml"
77+
xml.write_text(SAMPLE_TMPL.format(id="one"), encoding="utf8")
78+
tree = etree.parse(str(xml))
79+
out = tei2json.extract_json(tree)
80+
# expected keys
81+
assert "title" in out
82+
assert out["title"][0].startswith("Sample Title")
83+
assert "syrTitle" in out
84+
assert out["idno"].endswith("/one")
85+
assert "displayTitleEnglish" in out
86+
assert "persName" in out and any("Person" in p for p in out["persName"])
87+
assert "placeName" in out and any("Place" in pl for pl in out["placeName"])
88+
assert "finalRubrics" in out and any("ܪܘܒܪܝܩ" in r for r in out["finalRubrics"])
89+
assert "colophons" in out and any("Colophon" in c for c in out["colophons"])
90+
91+
92+
def test_process_directory_and_bulk(sample_dir, tmp_path):
93+
# process directory with the module's process_file function (simulate CLI)
94+
outdir = tmp_path / "json_output"
95+
outdir.mkdir()
96+
bulk_file = tmp_path / "bulk.json"
97+
# use the public functions: process_file returns dict
98+
results = {}
99+
for xml in sorted(sample_dir.glob("*.xml")):
100+
data = tei2json.process_file(xml)
101+
results[xml.stem] = data
102+
# write single-file JSON to outdir to mimic --outdir behavior
103+
(outdir / (xml.stem + ".json")).write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf8")
104+
105+
# Now create a bulk file using same logic as script
106+
with open(bulk_file, "w", encoding="utf8") as fh:
107+
for k in sorted(results.keys()):
108+
meta = {"index": {"_index": "britishlibrary-index-1", "_id": f"ms-{k}"}}
109+
fh.write(json.dumps(meta, ensure_ascii=False) + "\n")
110+
fh.write(json.dumps(results[k], ensure_ascii=False) + "\n")
111+
112+
# Assertions
113+
written = list(outdir.glob("*.json"))
114+
assert len(written) == 5
115+
bf = bulk_file.read_text(encoding="utf8")
116+
# bulk must contain 10 lines (2 lines per doc)
117+
assert bf.count("\n") >= 10
118+
# quick spot checks:
119+
assert '"_index": "britishlibrary-index-1"' in bf
120+
assert '"_id": "ms-1"' in bf
121+
122+
123+
def test_handles_missing_optional_elements(tmp_path):
124+
# Create a TEI missing persName/placeName to ensure code doesn't crash
125+
minimal = """<?xml version="1.0"?>
126+
<TEI xmlns="http://www.tei-c.org/ns/1.0">
127+
<teiHeader><fileDesc><titleStmt><title>Minimal</title></titleStmt></fileDesc></teiHeader>
128+
</TEI>"""
129+
f = tmp_path / "min.xml"
130+
f.write_text(minimal, encoding="utf8")
131+
tree = etree.parse(str(f))
132+
out = tei2json.extract_json(tree)
133+
# title should exist
134+
assert "title" in out or "displayTitleEnglish" in out
135+
# missing optional keys should not be present
136+
assert "persName" not in out or isinstance(out.get("persName"), list)
137+
138+
139+
def test_unicode_preserved(sample_dir):
140+
# Use one file and assert Unicode (Syriac) kept in output
141+
xml = sample_dir / "1.xml"
142+
tree = etree.parse(str(xml))
143+
out = tei2json.extract_json(tree)
144+
# the finalRubric contains Syriac chars from template
145+
assert any("ܪܘܒܪܝܩ" in r for r in out.get("finalRubrics", []))

0 commit comments

Comments
 (0)