Coverage for test_util.py: 96%

1"""

2 Test the util module of the edictor package.

3"""

4 from pathlib import Path

5 from pytest import raises

6 from 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 )

13 import os

14 import tempfile

15 import json

16

17 try:

18 from lingpy.compare.partial import Partial

19 from lingpy.compare.lexstat import LexStat

20 with_lingpy = True

21 except ImportError:

22 with_lingpy = False

23

24 try:

25 from lingrex.copar import CoPaR

26 with_lingrex = True

27 except ImportError:

28 with_lingrex = False

29

30

31 class Writer:

32

33 def write(self, x):

34

35 self.written = x

36

37

38 class 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

56 def 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

66 def test_edictor_path():

67 p = edictor_path("a.tsv")

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

69

70

71 def test_parse_args():

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

73

74

75 def 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

81 def 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

93 def test_send_response():

94

95 s = Sender()

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

97

98

99 def 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

106 def test_check():

107 s = Sender()

108 check(s)

109

110

111 def 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

137 def test_file_type():

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

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

140

141

142 def test_file_name():

143

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

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

146

147

148 def 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

173 def 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

195 def 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

213 def 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

232 def 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

251 def 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

280 def 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

321 def 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

337 def 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 )