def getElementsBy(start_node: ParentNode, cond: Callable[['Element'], bool]) -> NodeList: """Return list of child elements of start_node which matches ``cond``. ``cond`` must be a function which gets a single argument ``Element``, and returns boolean. If the node matches requested condition, ``cond`` should return True. This searches all child elements recursively. :arg ParentNode start_node: :arg cond: Callable[[Element], bool] :rtype: NodeList[Element] """ elements = [] for child in start_node.children: if cond(child): elements.append(child) elements.extend(child.getElementsBy(cond)) return NodeList(elements)
class TestNodeList(TestCase): def setUp(self): super().setUp() self.nl = NodeList(list(range(3))) def test_length(self): self.assertEqual(self.nl.length, 3) self.assertEqual(len(self.nl), 3) def test_index_access(self): self.assertEqual(self.nl[1], 1) self.assertEqual(self.nl[-1], 2) self.assertEqual(self.nl[1:2], [1]) with self.assertRaises(IndexError): self.nl[5] def test_item(self): self.assertEqual(self.nl.item(1), 1) self.assertEqual(self.nl.item(-1), None) self.assertEqual(self.nl.item(5), None) with self.assertRaises(TypeError): self.nl.item(slice(1, 2)) def test_contains(self): self.assertTrue(1 in self.nl) self.assertFalse(5 in self.nl) def test_iteration(self): l = [0, 1, 2] for n in self.nl: self.assertEqual(n, l.pop(0)) l = [2, 1, 0] for n in reversed(self.nl): self.assertEqual(n, l.pop(0)) def test_index(self): self.assertEqual(self.nl.index(0), 0) self.assertEqual(self.nl.index(1), 1) self.assertEqual(self.nl.index(2), 2)
def setUp(self): super().setUp() self.nl = NodeList(list(range(3)))
def selectedOptions(self) -> NodeList: """Return all selected option nodes.""" return NodeList(list(opt for opt in self.options if opt.selected))