Coverage for gws-app/gws/lib/xmlx/_test/element_test.py: 100%

309 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-16 23:09 +0200

1"""Tests for the element module""" 

2 

3import pytest 

4import gws 

5 

6import gws.lib.xmlx.element 

7 

8 

9def _make(*args, **kwargs): 

10 return gws.lib.xmlx.element.XmlElement(*args, **kwargs) 

11 

12 

13def test_init(): 

14 # Test basic initialization 

15 e = _make('test') 

16 assert e.tag == 'test' 

17 assert e.name == 'test' 

18 assert e.lcName == 'test' 

19 assert e.text == '' 

20 assert e.tail == '' 

21 assert e.attrib == {} 

22 assert len(e) == 0 

23 

24 # Test with attributes 

25 e = _make('test', {'attr1': 'value1'}, attr2='value2') 

26 assert e.attrib == {'attr1': 'value1', 'attr2': 'value2'} 

27 

28 

29def test_repr(): 

30 e = _make('test') 

31 repr_str = repr(e) 

32 assert 'XmlElement' in repr_str 

33 assert "'test'" in repr_str 

34 

35 

36def test_makeelement(): 

37 e = _make('parent') 

38 child = e.makeelement('child', {'attr': 'value'}) 

39 assert isinstance(child, e.__class__) 

40 assert child.tag == 'child' 

41 assert child.attrib == {'attr': 'value'} 

42 

43 

44def test_copy(): 

45 e = _make('test', {'attr': 'value'}) 

46 e.text = 'hello' 

47 e.tail = 'world' 

48 child = _make('child') 

49 e.append(child) 

50 

51 copied = e.__copy__() 

52 assert copied.tag == e.tag 

53 assert copied.attrib == e.attrib 

54 assert copied.text == e.text 

55 assert copied.tail == e.tail 

56 assert len(copied) == len(e) 

57 assert copied[0].tag == 'child' 

58 

59 

60def test_len(): 

61 e = _make('parent') 

62 assert len(e) == 0 

63 

64 e.append(_make('child1')) 

65 assert len(e) == 1 

66 

67 e.append(_make('child2')) 

68 assert len(e) == 2 

69 

70 

71def test_getitem_setitem_delitem(): 

72 parent = _make('parent') 

73 child1 = _make('child1') 

74 child2 = _make('child2') 

75 child3 = _make('child3') 

76 

77 parent.append(child1) 

78 parent.append(child2) 

79 

80 # Test getitem 

81 assert parent[0] is child1 

82 assert parent[1] is child2 

83 

84 # Test setitem 

85 parent[1] = child3 

86 assert parent[1] is child3 

87 

88 # Test delitem 

89 del parent[0] 

90 assert len(parent) == 1 

91 assert parent[0] is child3 

92 

93 

94def test_append(): 

95 parent = _make('parent') 

96 child = _make('child') 

97 

98 parent.append(child) 

99 assert len(parent) == 1 

100 assert parent[0] is child 

101 

102 

103def test_extend(): 

104 parent = _make('parent') 

105 child1 = _make('child1') 

106 child2 = _make('child2') 

107 

108 parent.extend([child1, child2]) 

109 assert len(parent) == 2 

110 assert parent[0] is child1 

111 assert parent[1] is child2 

112 

113 

114def test_insert(): 

115 parent = _make('parent') 

116 child1 = _make('child1') 

117 child2 = _make('child2') 

118 child3 = _make('child3') 

119 

120 parent.append(child1) 

121 parent.append(child2) 

122 parent.insert(1, child3) 

123 

124 assert len(parent) == 3 

125 assert parent[0] is child1 

126 assert parent[1] is child3 

127 assert parent[2] is child2 

128 

129 

130def test_remove(): 

131 parent = _make('parent') 

132 child1 = _make('child1') 

133 child2 = _make('child2') 

134 

135 parent.append(child1) 

136 parent.append(child2) 

137 parent.remove(child1) 

138 

139 assert len(parent) == 1 

140 assert parent[0] is child2 

141 

142 

143def test_find(): 

144 parent = _make('parent') 

145 child1 = _make('child') 

146 child2 = _make('other') 

147 

148 parent.append(child1) 

149 parent.append(child2) 

150 

151 found = parent.find('child') 

152 assert found is child1 

153 

154 not_found = parent.find('nonexistent') 

155 assert not_found is None 

156 

157 

158def test_findtext(): 

159 parent = _make('parent') 

160 child = _make('child') 

161 child.text = 'test text' 

162 parent.append(child) 

163 

164 text = parent.findtext('child') 

165 assert text == 'test text' 

166 

167 default_text = parent.findtext('nonexistent', 'default') 

168 assert default_text == 'default' 

169 

170 

171def test_findall(): 

172 parent = _make('parent') 

173 child1 = _make('child') 

174 child2 = _make('child') 

175 other = _make('other') 

176 

177 parent.append(child1) 

178 parent.append(child2) 

179 parent.append(other) 

180 

181 children = parent.findall('child') 

182 assert len(children) == 2 

183 assert child1 in children 

184 assert child2 in children 

185 

186 

187def test_iterfind(): 

188 parent = _make('parent') 

189 child1 = _make('child') 

190 child2 = _make('child') 

191 

192 parent.append(child1) 

193 parent.append(child2) 

194 

195 found_children = list(parent.iterfind('child')) 

196 assert len(found_children) == 2 

197 assert child1 in found_children 

198 assert child2 in found_children 

199 

200 

201def test_clear(): 

202 e = _make('test', {'attr': 'value'}) 

203 e.text = 'hello' 

204 e.tail = 'world' 

205 e.append(_make('child')) 

206 

207 e.clear() 

208 assert e.attrib == {} 

209 assert e.text == '' 

210 assert e.tail == '' 

211 assert len(e) == 0 

212 

213 

214def test_get_set(): 

215 e = _make('test') 

216 

217 # Test get with default 

218 assert e.get('nonexistent') is None 

219 assert e.get('nonexistent', 'default') == 'default' 

220 

221 # Test set and get 

222 e.set('attr', 'value') 

223 assert e.get('attr') == 'value' 

224 

225 

226def test_keys(): 

227 e = _make('test', {'attr1': 'value1', 'attr2': 'value2'}) 

228 keys = list(e.keys()) 

229 assert 'attr1' in keys 

230 assert 'attr2' in keys 

231 assert len(keys) == 2 

232 

233 

234def test_items(): 

235 e = _make('test', {'attr1': 'value1', 'attr2': 'value2'}) 

236 items = list(e.items()) 

237 assert ('attr1', 'value1') in items 

238 assert ('attr2', 'value2') in items 

239 assert len(items) == 2 

240 

241 

242def test_iter(): 

243 parent = _make('parent') 

244 child1 = _make('child') 

245 child2 = _make('other') 

246 grandchild = _make('child') 

247 child1.append(grandchild) 

248 

249 parent.append(child1) 

250 parent.append(child2) 

251 

252 # Test iter all 

253 all_elements = list(parent.iter()) 

254 assert len(all_elements) == 4 # parent, child1, grandchild, child2 

255 assert parent in all_elements 

256 assert child1 in all_elements 

257 assert grandchild in all_elements 

258 assert child2 in all_elements 

259 

260 # Test iter with tag 

261 child_elements = list(parent.iter('child')) 

262 assert len(child_elements) == 2 

263 assert child1 in child_elements 

264 assert grandchild in child_elements 

265 

266 # Test iter with '*' 

267 all_with_star = list(parent.iter('*')) 

268 assert len(all_with_star) == 4 

269 

270 

271def test_itertext(): 

272 parent = _make('parent') 

273 parent.text = 'parent text' 

274 

275 child = _make('child') 

276 child.text = 'child text' 

277 child.tail = 'child tail' 

278 

279 parent.append(child) 

280 

281 texts = list(parent.itertext()) 

282 assert 'parent text' in texts 

283 assert 'child text' in texts 

284 assert 'child tail' in texts 

285 

286 

287def test_bool(): 

288 e = _make('test') 

289 assert bool(e) is True 

290 

291 

292def test_iter_children(): 

293 parent = _make('parent') 

294 child1 = _make('child1') 

295 child2 = _make('child2') 

296 

297 parent.append(child1) 

298 parent.append(child2) 

299 

300 children = list(parent) 

301 assert len(children) == 2 

302 assert child1 in children 

303 assert child2 in children 

304 

305 

306def test_children(): 

307 parent = _make('parent') 

308 child1 = _make('child1') 

309 child2 = _make('child2') 

310 

311 parent.append(child1) 

312 parent.append(child2) 

313 

314 children = parent.children() 

315 assert len(children) == 2 

316 assert child1 in children 

317 assert child2 in children 

318 

319 

320def test_has(): 

321 e = _make('test', {'attr1': 'value1'}) 

322 assert e.has('attr1') is True 

323 assert e.has('nonexistent') is False 

324 

325 

326def test_add(): 

327 parent = _make('parent') 

328 child = parent.add('child', {'attr': 'value'}, extra='extra_value') 

329 

330 assert len(parent) == 1 

331 assert parent[0] is child 

332 assert child.tag == 'child' 

333 assert child.attrib == {'attr': 'value', 'extra': 'extra_value'} 

334 

335 

336def test_attr(): 

337 e = _make('test', {'attr1': 'value1'}) 

338 assert e.attr('attr1') == 'value1' 

339 assert e.attr('nonexistent') == '' 

340 assert e.attr('nonexistent', 'default') == 'default' 

341 

342 

343def test_findfirst(): 

344 parent = _make('parent') 

345 child1 = _make('child1') 

346 child2 = _make('child2') 

347 child3 = _make('child3') 

348 

349 parent.append(child1) 

350 parent.append(child2) 

351 parent.append(child3) 

352 

353 # Test with no arguments - returns first child 

354 first = parent.findfirst() 

355 assert first is child1 

356 

357 # Test with paths 

358 found = parent.findfirst('child2', 'child3') 

359 assert found is child2 

360 

361 # Test when nothing found 

362 not_found = parent.findfirst('nonexistent') 

363 assert not_found is None 

364 

365 # Test empty parent 

366 empty_parent = _make('empty') 

367 assert empty_parent.findfirst() is None 

368 

369 

370def test_textof(): 

371 parent = _make('parent') 

372 child1 = _make('child1') 

373 child1.text = 'text1' 

374 child2 = _make('child2') 

375 child2.text = 'text2' 

376 

377 parent.append(child1) 

378 parent.append(child2) 

379 

380 text = parent.textof('child1', 'child3') 

381 assert text == 'text1' 

382 

383 no_text = parent.textof('nonexistent') 

384 assert no_text is None 

385 

386 

387def test_textlist(): 

388 parent = _make('parent') 

389 child1 = _make('item') 

390 child1.text = 'text1' 

391 child2 = _make('item') 

392 child2.text = 'text2' 

393 child3 = _make('other') 

394 child3.text = 'text3' 

395 

396 parent.append(child1) 

397 parent.append(child2) 

398 parent.append(child3) 

399 

400 # Test without paths - gets all children text 

401 all_texts = parent.textlist() 

402 assert 'text1' in all_texts 

403 assert 'text2' in all_texts 

404 assert 'text3' in all_texts 

405 

406 # Test with specific path 

407 item_texts = parent.textlist('item') 

408 assert item_texts == ['text1', 'text2'] 

409 

410 # Test deep option 

411 grandchild = _make('grandchild') 

412 grandchild.text = 'deep text' 

413 child1.append(grandchild) 

414 

415 shallow_texts = parent.textlist('item', deep=False) 

416 assert 'deep text' not in shallow_texts 

417 

418 deep_texts = parent.textlist('item', deep=True) 

419 assert 'deep text' in deep_texts 

420 

421 

422def test_textdict(): 

423 parent = _make('parent') 

424 child1 = _make('name') 

425 child1.text = 'John' 

426 child2 = _make('age') 

427 child2.text = '30' 

428 

429 parent.append(child1) 

430 parent.append(child2) 

431 

432 text_dict = parent.textdict() 

433 assert text_dict == {'name': 'John', 'age': '30'} 

434 

435 # Test with specific paths 

436 name_dict = parent.textdict('name') 

437 assert name_dict == {'name': 'John'} 

438 

439 # Test deep option 

440 container = _make('container') 

441 nested = _make('nested') 

442 nested.text = 'nested value' 

443 container.append(nested) 

444 parent.append(container) 

445 

446 shallow_dict = parent.textdict('container', deep=False) 

447 assert 'nested' not in shallow_dict 

448 

449 deep_dict = parent.textdict('container', deep=True) 

450 assert 'nested' in deep_dict 

451 assert deep_dict['nested'] == 'nested value'