from collections import OrderedDict from datetime import datetime import pytest from components.datagrid.DataGrid import * from helpers import matches, extract_popup_content, extract_table_values, Empty, to_array, search_elements_by_name, get_selected, \ get_context_menu TEST_GRID_ID = "testing_grid_id" @pytest.fixture() def dg(): df = pd.DataFrame({ 'Name': ['Alice', 'Bob'], 'Age': [20, 25] }) return DataGrid(df, id=TEST_GRID_ID) @pytest.fixture() def dg2(): """ More elements :return: """ df = pd.DataFrame({ 'Name': ['Alice', 'Bob', 'Charlie', 'David'], 'Age': [20, 25, 30, 35], 'City': ['New York', 'Los Angeles', 'Chicago', 'Houston'], 'Student': [True, False, True, False], 'Date': [datetime(2020, 1, 10), datetime(2022, 10, 1), datetime(2007, 1, 1), datetime(2000, 12, 31), ] }) return DataGrid(df, id=TEST_GRID_ID) @pytest.fixture() def grid_id(dg): return dg.get_grid_id() def test_i_can_manage_instance(): datagrid_1 = DataGrid(id="id1") datagrid_2 = DataGrid(id="id2") datagrid_3 = DataGrid(id="id1") assert datagrid_1 is not datagrid_2 assert datagrid_1 is datagrid_3 def test_i_can_render_empty_data_grid(): grid_id = "testing_grid" dg = DataGrid(id=grid_id) expected = Div( Div(), # container for keyboard handlers Div( Div(id=f"tt_datagrid-{grid_id}"), # tooltip Div(id=f"fa_datagrid-{grid_id}"), # filter component Div(name="dt-controls"), # reset filter, resize, ... cls="flex justify-between"), Div( Div(id=f"tsm_datagrid-{grid_id}"), # selection management Div(id=f"tdd_datagrid-{grid_id}"), # drag and drop indicator Div(id=f"tcdd_datagrid-{grid_id}"), # cell drop down Div(), # navigation keyboards Div( Div(id=f"th_datagrid-{grid_id}"), Div(id=f"tb_datagrid-{grid_id}"), Div(id=f"tf_datagrid-{grid_id}"), ), Script(), id=f"t_datagrid-{grid_id}", cls="dt-table" ) ) res = dg.__ft__() assert matches(res, expected) def test_test_there_is_no_filter_input_when_gs_filter_input_is_false(): grid_id = "testing_grid" grid_setting = {DG_FILTER_INPUT: False} dg = DataGrid(id=grid_id, grid_settings=grid_setting) expected = Div( Div(), # container for keyboard handlers Div( Div(id=f"tt_datagrid-{grid_id}"), # tooltip Div(Empty), # filter component Div(name="dt-controls"), # reset filter, resize, ... cls="flex justify-between"), Div( Div(id=f"tsm_datagrid-{grid_id}"), # selection management Div(id=f"tdd_datagrid-{grid_id}"), # drag and drop indicator Div(id=f"tcdd_datagrid-{grid_id}"), # cell drop down Div(), # navigation keyboards Div( Div(id=f"th_datagrid-{grid_id}"), Div(id=f"tb_datagrid-{grid_id}"), Div(id=f"tf_datagrid-{grid_id}")), Script(), id=f"t_datagrid-{grid_id}", cls="dt-table" ) ) res = dg.__ft__() assert matches(res, expected) def test_there_is_no_filter_button_in_header_when_gs_filter_input_is_false(): grid_id = "testing_grid" grid_setting = {DG_FILTER_INPUT: False} df = pd.DataFrame({ 'Name': ['Alice', 'Bob'], 'Age': [20, 25] }) dg = DataGrid(df, id=grid_id, grid_settings=grid_setting) header = dg.mk_table_header() expected = Div( Div( Div(Div("Name")), # name Div(Div()), # sort Div(), # column clickable extension Div(Empty), # No filtering icon Div(Empty), # No filtering icon Div(), # resize handle cls='dt-cell dt-draggable dt-resizable', data_col='name'), Div( Div(Div("Age")), # name Div(Div()), # sort Div(), # column clickable extension Div(Empty), # No filtering icon Div(Empty), # No filtering icon Div(), # resize handle cls='dt-cell dt-draggable dt-resizable', data_col='age'), ) assert matches(header, expected) def test_i_can_generate_grid_html(dg, grid_id): resize_attr = {"hx-on::after-settle": f"setColumnsWidths('{grid_id}', false);"} expected = Div( Div( Div( Div(Div("Name")), Div(Div(), hx_post=f"/{DATAGRID_PATH}/sort"), # sort Div(cls="dt-flex-grow"), # column clickable extension Div(cls='icon-24 dt-filter-icon icon-btn'), Div(cls="dt-filter-popup"), Div(cls="dt-resize-handle"), data_col="name" ), Div( Div(Div("Age")), Div(Div(), hx_post=f"/{DATAGRID_PATH}/sort"), # sort Div(cls="dt-flex-grow"), # column clickable extension Div(cls='icon-24 dt-filter-icon icon-btn'), Div(cls="dt-filter-popup"), Div(cls="dt-resize-handle"), data_col="age" ), cls="dt-row dt-header", id=f"th_{grid_id}"), Div( Div( Div(Div("Alice"), data_col="name"), Div(Div("20"), data_col="age"), ), Div( Div(Div("Bob"), data_col="name"), Div(Div("25"), data_col="age"), ), cls="dt-body", id=f"tb_{grid_id}", **resize_attr, ), Div( Div( Div(Div(), data_col="name"), Div(Div(), data_col="age"), ), id=f"tf_{grid_id}") ) res = dg.mk_table() table = search_elements_by_name(res, None, {"class": "dt-inner-table"})[0] # as_ft = debug_print(res) matches(table, expected) def test_i_can_render_boolean(): df = pd.DataFrame({ 'Name': ['Alice', 'Bob'], 'Age': [20, 25], 'Is_Good': [True, False] }) dg = DataGrid(df) _grid_id = dg.get_grid_id() expected = Div( Div( Div(Div("Alice")), Div(Div("20")), Div(Div(NotStr('