Coverage for test_util.py: 96%

156 statements  

« 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 

16 

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 

23 

24try: 

25 from lingrex.copar import CoPaR 

26 with_lingrex = True 

27except ImportError: 

28 with_lingrex = False 

29 

30 

31class Writer: 

32 

33 def write(self, x): 

34 

35 self.written = x 

36 

37 

38class Sender: 

39 

40 def __init__(self): 

41 

42 self.wfile = Writer() 

43 

44 def send_response(self, x): 

45 pass 

46 

47 def send_header(self, x, y): 

48 

49 pass 

50 

51 def end_headers(self): 

52 

53 pass 

54 

55 

56def test_opendb(): 

57 

58 os.chdir(Path(__file__).parent) 

59 

60 a, b = opendb("germanic", {"sqlite": "data"}) 

61 a, b = opendb("test", {"sqlite": "data"}) 

62 

63 raises(ValueError, opendb, "germanict", {"sqlite": "data"}) 

64 

65 

66def test_edictor_path(): 

67 p = edictor_path("a.tsv") 

68 assert p.name == "a.tsv" 

69 

70 

71def test_parse_args(): 

72 assert parse_args("bla.html?file=good&remote=not")["file"] == "good" 

73 

74 

75def test_parse_post(): 

76 

77 parse_post("file=a&file2=b&file3=d") 

78 parse_post(b"file=a&file2=b&file3=d") 

79 

80 

81def test_download(): 

82 

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) 

91 

92 

93def test_send_response(): 

94 

95 s = Sender() 

96 send_response(s, "test", content_disposition="txt", encode=None) 

97 

98 

99def test_handle_args(): 

100 

101 args = {} 

102 handle_args(args, "a=b&c=d", "POST") 

103 handle_args(args, "?c=d&e=f", "GET") 

104 

105 

106def test_check(): 

107 s = Sender() 

108 check(s) 

109 

110 

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() 

135 

136 

137def test_file_type(): 

138 assert file_type("plain.html?file=test") == "html" 

139 assert file_type("test.txt") == "txt" 

140 

141 

142def test_file_name(): 

143 

144 assert file_name("plain.html?file=test") == "plain.html" 

145 assert file_name("test.txt") == "test.txt" 

146 

147 

148def test_file_handler(): 

149 

150 s = Sender() 

151 file_handler(s, "js", "/text.js") 

152 assert s.wfile.written == b"404 FNF" 

153 

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") 

158 

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") 

162 

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) 

171 

172 

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 ) 

193 

194 

195def test_cognates(): 

196 if not with_lingpy: 

197 return 

198 

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" 

203 

204 cognates(s, data, "POST") 

205 

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" 

209 

210 cognates(s, data, "POST") 

211 

212 

213def test_alignments(): 

214 

215 if not with_lingpy: 

216 return 

217 

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" 

222 

223 alignments(s, data, "POST") 

224 

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" 

228 

229 alignments(s, data, "POST") 

230 

231 

232def test_patterns(): 

233 

234 if not with_lingrex: 

235 return 

236 

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" 

241 

242 patterns(s, data, "POST") 

243 

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" 

247 

248 patterns(s, data, "POST") 

249 

250 

251def test_new_id(): 

252 

253 s = Sender() 

254 

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 

263 

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 ) 

271 

272 new_id( 

273 s, 

274 "new_id=COGID&file=germanic&remote_dbase=germanic", 

275 "POST", 

276 {"sqlite": "sqlite", "remote_dbase": "germanic.sqlite3"} 

277 ) 

278 

279 

280def test_triples(): 

281 

282 s = Sender() 

283 

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" 

292 

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" 

301 

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" 

310 

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" 

319 

320 

321def test_modifications(): 

322 

323 s = Sender() 

324 

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" 

333 

334 modifications(s, "file=germanic", "POST", {}) 

335 

336 

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 ) 

352 

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 )