First Working version. I can add table
This commit is contained in:
331
tests/test_helpers.py
Normal file
331
tests/test_helpers.py
Normal file
@@ -0,0 +1,331 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
import pandas as pd
|
||||
import pytest
|
||||
from fastcore.basics import NotStr
|
||||
from fastcore.xml import to_xml
|
||||
from fasthtml.components import *
|
||||
|
||||
from components.datagrid.DataGrid import DataGrid
|
||||
from helpers import matches, search_elements_by_name, search_elements_by_path, extract_table_values, get_from_html, \
|
||||
extract_popup_content, \
|
||||
Empty, get_path_attributes, find_first_match, StartsWith, search_first_with_attribute, Contains
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_structure():
|
||||
"""
|
||||
A pytest fixture to provide a sample tree structure for testing.
|
||||
"""
|
||||
return Html(
|
||||
Header(cls="first-class"),
|
||||
Body(
|
||||
"hello world",
|
||||
Div(
|
||||
Span(cls="highlight"),
|
||||
Span(id="inner", name="child"),
|
||||
id="content"),
|
||||
),
|
||||
Footer(),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, expected, expected_error", [
|
||||
(Div(), "value",
|
||||
"The types are different: <class 'fastcore.xml.FT'> != <class 'str'>, (div((),{}) != value)."),
|
||||
(Div(), A(),
|
||||
"The elements are different: 'div' != 'a'."),
|
||||
(Div(Div()), Div(A()),
|
||||
"Path 'div':\n\tThe elements are different: 'div' != 'a'."),
|
||||
(Div(A(Span())), Div(A("element")),
|
||||
"Path 'div.a':\n\tThe types are different: <class 'fastcore.xml.FT'> != <class 'str'>, (span((),{}) != element)."),
|
||||
(Div(attr="one"), Div(attr="two"),
|
||||
"Path 'div':\n\tThe values are different for 'attr' : 'one' != 'two'."),
|
||||
(Div(A(attr="alpha")), Div(A(attr="beta")),
|
||||
"Path 'div.a':\n\tThe values are different for 'attr' : 'alpha' != 'beta'."),
|
||||
(Div(Div(), A()), Div(Div(), Span()),
|
||||
"Path 'div':\n\tThe elements are different: 'a' != 'span'."),
|
||||
(Div(A()), Div(A(attr="beta")),
|
||||
"Path 'div.a':\n\tAttribute 'attr' is not found (with expected value: 'beta'). actual='{}'."),
|
||||
(Div(id="one"), Div(id="two"),
|
||||
"Path 'div#one':\n\tThe values are different for 'id' : 'one' != 'two'."),
|
||||
(Div(id="same_id", attr="one"), Div(id="same_id", attr="two"),
|
||||
"Path 'div#same_id':\n\tThe values are different for 'attr' : 'one' != 'two'."),
|
||||
(Div(name="same_name", attr="one"), Div(name="same_name", attr="two"),
|
||||
"Path 'div[name=same_name]':\n\tThe values are different for 'attr' : 'one' != 'two'."),
|
||||
(Div(cls="same_class", attr="one"), Div(cls="same_class", attr="two"),
|
||||
"Path 'div[class=same_class]':\n\tThe values are different for 'attr' : 'one' != 'two'."),
|
||||
(Div(attr="value"), Div(Empty),
|
||||
"Empty element expected, but found attributes {'attr': 'value'}."),
|
||||
(Div(Div()), Div(Empty),
|
||||
"Empty element expected, but found children (div((),{}),)."),
|
||||
(Div(cls="a long attr"), Div(cls=StartsWith("different start")),
|
||||
"Path 'div[class=a long attr]':\n\tAttribute 'class' does not start with 'different start': actual='a long attr', expected ='different start'."),
|
||||
(Div(cls="a long attr"), Div(cls=Contains("not included")),
|
||||
"Path 'div[class=a long attr]':\n\tAttribute 'class' does not contain 'not included': actual='a long attr', expected ='not included'."),
|
||||
|
||||
])
|
||||
def test_matches_error_expected(value, expected, expected_error):
|
||||
with pytest.raises(AssertionError) as error:
|
||||
matches(value, expected)
|
||||
|
||||
assert error.value.args[0] == expected_error
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, expected", [
|
||||
(Div(), Div()),
|
||||
(Div(A()), Div(A())),
|
||||
(Div(id='do_not_validate'), Div(id='do_not_validate')),
|
||||
(Div(A()), Div()), # children of actual are not selected
|
||||
(Div(A(), Span(id="validate_please"), A(id="do_not_care")), Div(A(), Span(id="validate_please"))),
|
||||
(Div(), Div(Empty)),
|
||||
(Div(cls="a long attr"), Div(cls=StartsWith("a long"))),
|
||||
(Div(cls="a long attr"), Div(cls=Contains("long"))),
|
||||
])
|
||||
def test_matches_success_expected(value, expected):
|
||||
assert matches(value, expected)
|
||||
|
||||
|
||||
def test_i_can_search_elements_by_name():
|
||||
to_find = Table()
|
||||
res = search_elements_by_name(to_find, "table")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_name(ft, "table")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "table")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(to_find, Span(to_find))
|
||||
res = search_elements_by_name(ft, "table")
|
||||
assert res == [to_find, to_find]
|
||||
|
||||
|
||||
def test_i_can_search_not_str_by_name():
|
||||
to_find = NotStr("Hello World")
|
||||
|
||||
res = search_elements_by_name(to_find, "NotStr")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_name(ft, "NotStr")
|
||||
assert res == [to_find]
|
||||
|
||||
|
||||
def test_i_can_search_elements_by_name_with_attr_and_exact_compare():
|
||||
to_find = Table(attr="value")
|
||||
|
||||
res = search_elements_by_name(to_find, None, {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, None, {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "other", {"attr": "value"})
|
||||
assert res == []
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value2"})
|
||||
assert res == []
|
||||
|
||||
ft = Div(Span(Table()))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value"})
|
||||
assert res == []
|
||||
|
||||
|
||||
def test_i_can_search_elements_by_name_with_attr_and_contains_compare():
|
||||
to_find = Table(attr="value1 value2 value3")
|
||||
|
||||
res = search_elements_by_name(to_find, None, {"attr": "value"}, comparison_method="contains")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, None, {"attr": "value"}, comparison_method="contains")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value"}, comparison_method="contains")
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "other", {"attr": "value"}, comparison_method="contains")
|
||||
assert res == []
|
||||
|
||||
ft = Div(Span(), Span(to_find))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value4"}, comparison_method="contains")
|
||||
assert res == []
|
||||
|
||||
ft = Div(Span(Table()))
|
||||
res = search_elements_by_name(ft, "table", {"attr": "value"}, comparison_method="contains")
|
||||
assert res == []
|
||||
|
||||
|
||||
def test_i_can_select_path():
|
||||
to_find = Table(attr="value")
|
||||
|
||||
res = search_elements_by_path(to_find, "table", None)
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_path(ft, "div.span.table", None)
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_path(ft, "span.table", None)
|
||||
assert res == [to_find]
|
||||
|
||||
|
||||
def test_i_can_select_path_with_attr():
|
||||
to_find = Table(attr="value")
|
||||
|
||||
res = search_elements_by_path(to_find, "table", {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_path(ft, "div.span.table", {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
ft = Div(Span(to_find))
|
||||
res = search_elements_by_path(ft, "span.table", {"attr": "value"})
|
||||
assert res == [to_find]
|
||||
|
||||
res = search_elements_by_path(to_find, "span.table", {"attr": "value2"})
|
||||
assert res == []
|
||||
|
||||
|
||||
def test_i_can_extract_table_values_from_ft():
|
||||
df = pd.DataFrame({
|
||||
'Name': ['Alice', 'Bob'],
|
||||
'Age': [20, 25]
|
||||
})
|
||||
dg = DataGrid(df, id="testing_grid_id")
|
||||
element = dg.__ft__()
|
||||
|
||||
assert extract_table_values(element) == OrderedDict({
|
||||
'Name': ['Alice', 'Bob'],
|
||||
'Age': ["20", "25"]
|
||||
})
|
||||
|
||||
assert extract_table_values(element, header=False) == [
|
||||
["Alice", "20"],
|
||||
["Bob", "25"]
|
||||
]
|
||||
|
||||
|
||||
def test_i_can_extract_table_values_from_html():
|
||||
df = pd.DataFrame({
|
||||
'Name': ['Alice', 'Bob'],
|
||||
'Age': [20, 25]
|
||||
})
|
||||
dg = DataGrid(df, id="testing_grid_id")
|
||||
html = to_xml(dg.__ft__())
|
||||
element = get_from_html(html)
|
||||
|
||||
assert extract_table_values(element) == OrderedDict({
|
||||
'Name': ['Alice', 'Bob'],
|
||||
'Age': ["20", "25"]
|
||||
})
|
||||
|
||||
assert extract_table_values(element, header=False) == [
|
||||
["Alice", "20"],
|
||||
["Bob", "25"]
|
||||
]
|
||||
|
||||
|
||||
def test_i_can_extract_popup_content_from_ft():
|
||||
df = pd.DataFrame({
|
||||
'Name': ['Alice', 'Bob', 'Charlie'],
|
||||
'Age': [20, 25, 30]
|
||||
})
|
||||
dg = DataGrid(df, id="testing_grid_id")
|
||||
element = dg.mk_filter_popup_content("name")
|
||||
|
||||
assert extract_popup_content(element) == OrderedDict(
|
||||
{'__filter_input__': '',
|
||||
'Alice': False,
|
||||
'Bob': False,
|
||||
'Charlie': False,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_i_can_extract_popup_content_from_html():
|
||||
df = pd.DataFrame({
|
||||
'Name': ['Alice', 'Bob', 'Charlie'],
|
||||
'Age': [20, 25, 30]
|
||||
})
|
||||
dg = DataGrid(df, id="testing_grid_id")
|
||||
html = to_xml(dg.mk_filter_popup_content("name"))
|
||||
element = get_from_html(html)
|
||||
|
||||
assert extract_popup_content(element) == OrderedDict(
|
||||
{'__filter_input__': '',
|
||||
'Alice': False,
|
||||
'Bob': False,
|
||||
'Charlie': False,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path, expected_attributes", [
|
||||
("div", {"tag": "div"}),
|
||||
("div#my_id", {"tag": "div", "id": "my_id"}),
|
||||
("div[class=my_class]", {"tag": "div", "class": "my_class"}),
|
||||
("div#my_id[class=my_class]", {"tag": "div", "id": "my_id", "class": "my_class"}),
|
||||
("div#my_id[a1=v1][a2=v2]", {"tag": "div", "id": "my_id", "a1": "v1", "a2": "v2"}),
|
||||
("div#my_id[a1='v1']", {"tag": "div", "id": "my_id", "a1": "v1"}),
|
||||
('div#my_id[a1="v1"]', {"tag": "div", "id": "my_id", "a1": "v1"}),
|
||||
("div#my_id[a1='v-1']", {"tag": "div", "id": "my_id", "a1": "v-1"}),
|
||||
("div#my_id[a1='v_1']", {"tag": "div", "id": "my_id", "a1": "v_1"}),
|
||||
])
|
||||
def test_i_can_get_path_attributes(path, expected_attributes):
|
||||
assert get_path_attributes(path) == expected_attributes
|
||||
|
||||
|
||||
def test_i_can_select_by_path():
|
||||
# I can select the good one from a list
|
||||
items = [Div(id='1'),
|
||||
Div(id='2'),
|
||||
Div(id='3')]
|
||||
actual = find_first_match(items, "div#3")
|
||||
assert actual == items[2]
|
||||
|
||||
# I can select using attribute
|
||||
item = Div(Span(id="span_1"), Span(id="span_2"), id="div_1")
|
||||
actual = find_first_match(item, "div.span#span_2")
|
||||
assert actual == item.children[1]
|
||||
|
||||
# I can manage when no ft
|
||||
items = [Div(Div("text")), Div(Div(Div(id="3"), id="2"), id="1")] # 'text' is not a ft, but there won't be any error
|
||||
actual = find_first_match(items, "div.div.div")
|
||||
assert actual.attrs["id"] == "3"
|
||||
|
||||
# None is returned when not found
|
||||
assert find_first_match(item, "div.span#span_3") is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("tag, attr, expected", [
|
||||
("span", "class", ("span", "highlight")), # The tag and the attribute exist
|
||||
("footer", "id", None), # The tag exists, but not the attribute
|
||||
(None, "class", ("header", "first-class")), # First element with a given attribute
|
||||
("p", "class", None), # The tag does not exist
|
||||
("span", "id", ("span", "inner")), # Inner element
|
||||
(None, "name", ("span", "child")), # Inner element
|
||||
])
|
||||
def test_i_can_search_first_with_attribute(tag, attr, expected, sample_structure):
|
||||
result = search_first_with_attribute(sample_structure, tag, attr)
|
||||
if expected is None:
|
||||
assert result is None
|
||||
else:
|
||||
assert result.tag == expected[0]
|
||||
assert attr in result.attrs
|
||||
assert result.attrs[attr] == expected[1]
|
||||
Reference in New Issue
Block a user