import pytest from fastcore.basics import NotStr from fasthtml.components import Div, Span, Main from myfasthtml.test.matcher import find, TestObject, Contains, StartsWith class Dummy: def __init__(self, attr1, attr2=None): self.attr1 = attr1 self.attr2 = attr2 def __eq__(self, other): return (isinstance(other, Dummy) and self.attr1 == other.attr1 and self.attr2 == other.attr2) def __hash__(self): return hash((self.attr1, self.attr2)) @pytest.mark.parametrize('ft, expected', [ ("hello", "hello"), (Div(id="id1"), Div(id="id1")), (Div(Span(id="span_id"), id="div_id1"), Div(Span(id="span_id"), id="div_id1")), (Div(id="id1", id2="id2"), Div(id="id1")), (Div(Div(id="id2"), id="id1"), Div(id="id1")), (Dummy(attr1="value"), Dummy(attr1="value")), (Dummy(attr1="value"), TestObject(Dummy, attr1="value")), (Div(attr="value1 value2"), Div(attr=Contains("value1"))), ]) def test_i_can_find(ft, expected): assert find(ft, expected) == [ft] def test_find_element_by_id_in_a_list(): a = Div(id="id1") b = Div(id="id2") c = Div(id="id3") assert find([a, b, c], b) == [b] def test_i_can_find_sub_element(): a = Div(id="id1") b = Span(a, id="id2") c = Main(b, id="id3") assert find(c, a) == [a] def test_i_can_find_when_pattern_appears_also_in_children(): a1 = Div(id="id1") b = Div(a1, id="id2") a2 = Div(b, id="id1") c = Main(a2, id="id3") assert find(c, a1) == [a2, a1] @pytest.mark.parametrize('ft, to_search, expected', [ (NotStr("hello"), NotStr("hello"), [NotStr("hello")]), (NotStr("hello my friend"), NotStr("hello"), NotStr("hello my friend")), (NotStr("hello"), TestObject(NotStr, s="hello"), [NotStr("hello")]), (NotStr("hello my friend"), TestObject(NotStr, s=StartsWith("hello")), NotStr("hello my friend")), ]) def test_i_can_manage_notstr_success_path(ft, to_search, expected): assert find(ft, to_search) == expected @pytest.mark.parametrize('ft, to_search', [ (NotStr("my friend"), NotStr("hello")), (NotStr("hello"), Dummy(attr1="hello")), # important, because of the internal __eq__ of NotStr (NotStr("hello my friend"), TestObject(NotStr, s="hello")), ]) def test_test_i_can_manage_notstr_failure_path(ft, to_search): with pytest.raises(AssertionError): find(ft, to_search) @pytest.mark.parametrize('ft, expected', [ (None, Div(id="id1")), (Span(id="id1"), Div(id="id1")), (Div(id2="id1"), Div(id="id1")), (Div(id="id2"), Div(id="id1")), ]) def test_i_cannot_find(ft, expected): with pytest.raises(AssertionError): find(expected, ft)