Coverage for test_util.py: 96%
156 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-07 06:52 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-07 06:52 +0200
1"""
2Test the util module of the edictor package.
3"""
4from pathlib import Path
5from pytest import raises
6from edictor.util import (
7 opendb, edictor_path, configuration, file_name,
8 file_type, file_handler, serve_base,
9 download, new_id, cognates, patterns, alignments, triples,
10 modifications, update, parse_args, parse_post,
11 send_response, handle_args, check
12 )
13import os
14import tempfile
15import json
17try:
18 from lingpy.compare.partial import Partial
19 from lingpy.compare.lexstat import LexStat
20 with_lingpy = True
21except ImportError:
22 with_lingpy = False
24try:
25 from lingrex.copar import CoPaR
26 with_lingrex = True
27except ImportError:
28 with_lingrex = False
31class Writer:
33 def write(self, x):
35 self.written = x
38class Sender:
40 def __init__(self):
42 self.wfile = Writer()
44 def send_response(self, x):
45 pass
47 def send_header(self, x, y):
49 pass
51 def end_headers(self):
53 pass
56def test_opendb():
58 os.chdir(Path(__file__).parent)
60 a, b = opendb("germanic", {"sqlite": "data"})
61 a, b = opendb("test", {"sqlite": "data"})
63 raises(ValueError, opendb, "germanict", {"sqlite": "data"})
66def test_edictor_path():
67 p = edictor_path("a.tsv")
68 assert p.name == "a.tsv"
71def test_parse_args():
72 assert parse_args("bla.html?file=good&remote=not")["file"] == "good"
75def test_parse_post():
77 parse_post("file=a&file2=b&file3=d")
78 parse_post(b"file=a&file2=b&file3=d")
81def test_download():
83 s = Sender()
84 wd = os.getcwd()
85 with tempfile.TemporaryDirectory() as t:
86 os.chdir(t)
87 download(s, "file=test.svt")
88 download(s, "file=test.tsv&data=abcdefg")
89 download(s, "file=test.tsv&data=abcdefg")
90 os.chdir(wd)
93def test_send_response():
95 s = Sender()
96 send_response(s, "test", content_disposition="txt", encode=None)
99def test_handle_args():
101 args = {}
102 handle_args(args, "a=b&c=d", "POST")
103 handle_args(args, "?c=d&e=f", "GET")
106def test_check():
107 s = Sender()
108 check(s)
111def test_configuration():
112 wd = os.getcwd()
113 with tempfile.TemporaryDirectory() as t:
114 os.chdir(t)
115 with open("config.json", "w") as f:
116 f.write(json.dumps(
117 {
118 "links": [
119 {
120 "url": "edictor.html",
121 "data": {
122 "file": "germanic",
123 "remote_dbase": "germanic",
124 "columns": "DOCULECT|CONCEPT|IPA|TOKENS|ALIGNMENT|COGID|PATTERNS|NOTE"
125 },
126 "name": "Germanic (SQLITE, Base)"
127 }
128 ]
129 }))
130 conf = configuration()
131 os.chdir(wd)
132 # next scenario that conf is missing in the current folder, so we take
133 # default conf
134 conf = configuration()
137def test_file_type():
138 assert file_type("plain.html?file=test") == "html"
139 assert file_type("test.txt") == "txt"
142def test_file_name():
144 assert file_name("plain.html?file=test") == "plain.html"
145 assert file_name("test.txt") == "test.txt"
148def test_file_handler():
150 s = Sender()
151 file_handler(s, "js", "/text.js")
152 assert s.wfile.written == b"404 FNF"
154 file_handler(s, "html", "/index.html")
155 file_handler(s, "png", "/edictor-small.png")
156 file_handler(s, "html", "/index-none.html")
157 file_handler(s, "png", "/edictor-none.png")
159 file_handler(s, "tsv", "/data/Germanic.tsv")
160 assert s.wfile.written[:2] == b"ID"
161 file_handler(s, "tsv", "/data/GER-none.tsv")
163 wd = os.getcwd()
164 with tempfile.TemporaryDirectory() as t:
165 os.chdir(t)
166 with open("test.tsv", "w") as f:
167 f.write("test")
168 file_handler(s, "tsv", "/data/test.tsv")
169 assert s.wfile.written == b"test"
170 os.chdir(wd)
173def test_serve_base():
174 s = Sender()
175 wd = os.getcwd()
176 with tempfile.TemporaryDirectory() as t:
177 os.chdir(t)
178 with open("test.tsv", "w") as f:
179 f.write("abcd")
180 serve_base(s, {"links": []})
181 os.chdir(wd)
182 serve_base(
183 s,
184 {"links": [{
185 "url": "edictor.html?file=GER.tsv",
186 "data": {
187 "file": "germanic",
188 "remote_dbase": "germanic",
189 "columns": "DOCULECT|CONCEPT|IPA|TOKENS|COGID|NOTE"
190 },
191 "name": "Germanic (Simple File)"}]}
192 )
195def test_cognates():
196 if not with_lingpy:
197 return
199 s = Sender()
200 data = "wordlist=1\tA\tA\tm a m a\n" + \
201 "2\tB\tA\tm u m u\n" + \
202 "3\tC\tA\tm i m i&mode=full"
204 cognates(s, data, "POST")
206 data = "wordlist=1\tA\tA\tm a m a\n" + \
207 "2\tB\tA\tm u m u\n" + \
208 "3\tC\tA\tm i m i&mode=partial"
210 cognates(s, data, "POST")
213def test_alignments():
215 if not with_lingpy:
216 return
218 s = Sender()
219 data = "wordlist=1\tA\tA\tm a m a\t1\n" + \
220 "2\tB\tA\tm u m u\t1\n" + \
221 "3\tC\tA\tm i m i\t1&mode=full"
223 alignments(s, data, "POST")
225 data = "wordlist=1\tA\tA\tm a m a\t1\n" + \
226 "2\tB\tA\tm u m u\t1\n" + \
227 "3\tC\tA\tm i m i\t1&mode=partial"
229 alignments(s, data, "POST")
232def test_patterns():
234 if not with_lingrex:
235 return
237 s = Sender()
238 data = "wordlist=1\tA\tA\tm a m a\t1\tm a m a\n" + \
239 "2\tB\tA\tm u m u\t1\tm u m u\n" + \
240 "3\tC\tA\tm i m i\tm i m i\t1&mode=full"
242 patterns(s, data, "POST")
244 data = "wordlist=1\tA\tA\tm a m a\t1\tm a m a\n" + \
245 "2\tB\tA\tm u m u\t1\tm u m u\n" + \
246 "3\tC\tA\tm i m i\tm i m i\t1&mode=partial"
248 patterns(s, data, "POST")
251def test_new_id():
253 s = Sender()
255 # test internally, in the test folder
256 new_id(
257 s,
258 "new_id=true&file=germanic&remote_dbase=germanic",
259 "POST",
260 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
261 )
262 assert int(s.wfile.written.strip()) == 1934
264 # test within edictor
265 new_id(
266 s,
267 "new_id=true&file=germanic&remote_dbase=germanic",
268 "POST",
269 {"sqlite": "sqlite", "remote_dbase": "germanic.sqlite3"}
270 )
272 new_id(
273 s,
274 "new_id=COGID&file=germanic&remote_dbase=germanic",
275 "POST",
276 {"sqlite": "sqlite", "remote_dbase": "germanic.sqlite3"}
277 )
280def test_triples():
282 s = Sender()
284 # test with POST
285 triples(
286 s,
287 "file=germanic&remote_dbase=germanic&doculects=German",
288 "POST",
289 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
290 )
291 assert s.wfile.written[:2] == b"ID"
293 # test with GET
294 triples(
295 s,
296 "?file=germanic&remote_dbase=germanic&doculects=German",
297 "GET",
298 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
299 )
300 assert s.wfile.written[:2] == b"ID"
302 # test with POST
303 triples(
304 s,
305 "file=germanic&remote_dbase=germanic&columns=ID%7CDOCULECT%7CCONCEPT%7CTOKENS",
306 "POST",
307 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
308 )
309 assert s.wfile.written[:2] == b"ID"
311 # test with concepts
312 triples(
313 s,
314 "file=germanic&remote_dbase=germanic&concepts=*markō",
315 "POST",
316 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
317 )
318 assert s.wfile.written[:2] == b"ID"
321def test_modifications():
323 s = Sender()
325 # test with POST
326 modifications(
327 s,
328 "file=germanic&remote_dbase=germanic&doculects=German&date=1654819200",
329 "POST",
330 {"sqlite": "data", "remote_dbase": "germanic.sqlite3"}
331 )
332 assert s.wfile.written[:2] == b"10"
334 modifications(s, "file=germanic", "POST", {})
337def test_update():
338 s = Sender()
339 # modify entries
340 update(
341 s,
342 "update=true&file=germanic&remote_dbase=germanicm&ids=42|||1694&cols=NOTE|||NOTE&vals=exc2|||exc2",
343 "POST",
344 {"sqlite": "data", "remote_dbase": "germanicm", "user": "edictor"}
345 )
346 update(
347 s,
348 "update=true&file=germanic&remote_dbase=germanicm&ids=42|||1694&cols=NOTE|||NOTE&vals=exc|||exc",
349 "POST",
350 {"sqlite": "data", "remote_dbase": "germanicm", "user": "edictor"}
351 )
353 # delete entries
354 update(
355 s,
356 "delete=true&file=germanic&remote_dbase=germanicm&ID=42",
357 "POST",
358 {"sqlite": "data", "remote_dbase": "germanicm", "user": "edictor"}
359 )
360 update(
361 s,
362 "update=true&file=germanic&remote_dbase=germanicm&ids=42|||42|||42&"
363 "cols=DOCULECT|||CONCEPT|||NOTE&vals=German|||*markō|||exc",
364 "POST",
365 {"sqlite": "data", "remote_dbase": "germanicm", "user": "edictor"}
366 )