feat: Enhance Data Components and Add SelectData Functionality (#3715)
## Changes Overview This PR introduces several enhancements to our data handling components and removes some legacy code: 1. **CreateData and UpdateData Components**: - Added text key name validation - Enhanced UpdateData to support updating and appending multiple data points - Implemented optional text key validator for dynamically loaded data - Updated component names, descriptions, and default values 2. **New SelectData Component**: - Implemented SelectDataComponent for data selection from a list - Added inputs for data list and index selection - Implemented error handling for out-of-range index selection 3. **Code Cleanup**: - Removed legacy post_code_processing methods from CreateDataComponent and UpdateDataComponent - Removed corresponding test cases 4. **Testing**: - Added unit tests for CreateData and UpdateData components - Updated test file names for consistency
This commit is contained in:
parent
1caba1cd7c
commit
ab2df9ef3d
5 changed files with 401 additions and 49 deletions
|
|
@ -0,0 +1,117 @@
|
|||
import pytest
|
||||
from langflow.components.prototypes.CreateData import CreateDataComponent
|
||||
from langflow.schema import Data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def create_data_component():
|
||||
return CreateDataComponent()
|
||||
|
||||
|
||||
def test_update_build_config(create_data_component):
|
||||
build_config = {
|
||||
"number_of_fields": {
|
||||
"type": "int",
|
||||
"value": 2,
|
||||
},
|
||||
"text_key": {
|
||||
"type": "str",
|
||||
"value": "",
|
||||
},
|
||||
"text_key_validator": {
|
||||
"type": "bool",
|
||||
"value": False,
|
||||
},
|
||||
}
|
||||
updated_config = create_data_component.update_build_config(
|
||||
build_config=build_config, field_value=3, field_name="number_of_fields"
|
||||
)
|
||||
|
||||
assert "field_1_key" in updated_config
|
||||
assert "field_2_key" in updated_config
|
||||
assert "field_3_key" in updated_config
|
||||
assert updated_config["number_of_fields"]["value"] == 3
|
||||
|
||||
|
||||
def test_update_build_config_exceed_limit(create_data_component):
|
||||
build_config = {
|
||||
"number_of_fields": {
|
||||
"type": "int",
|
||||
"value": 2,
|
||||
},
|
||||
"text_key": {
|
||||
"type": "str",
|
||||
"value": "",
|
||||
},
|
||||
"text_key_validator": {
|
||||
"type": "bool",
|
||||
"value": False,
|
||||
},
|
||||
}
|
||||
with pytest.raises(
|
||||
ValueError, match="Number of fields cannot exceed 15. Try using a Component to combine two Data."
|
||||
):
|
||||
create_data_component.update_build_config(build_config, 16, "number_of_fields")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_data(create_data_component):
|
||||
create_data_component._attributes = {
|
||||
"field_1_key": {"key1": "value1"},
|
||||
"field_2_key": {"key2": "value2"},
|
||||
}
|
||||
create_data_component.text_key = "key1"
|
||||
create_data_component.text_key_validator = False
|
||||
|
||||
result = await create_data_component.build_data()
|
||||
|
||||
assert isinstance(result, Data)
|
||||
assert result.data == {"key1": "value1", "key2": "value2"}
|
||||
assert result.text_key == "key1"
|
||||
|
||||
|
||||
def test_get_data(create_data_component):
|
||||
create_data_component._attributes = {
|
||||
"field_1_key": {"key1": "value1"},
|
||||
"field_2_key": {"key2": "value2"},
|
||||
}
|
||||
|
||||
result = create_data_component.get_data()
|
||||
|
||||
assert result == {"key1": "value1", "key2": "value2"}
|
||||
|
||||
|
||||
def test_validate_text_key_valid(create_data_component):
|
||||
# Arrange
|
||||
create_data_component._attributes = {
|
||||
"field_1_key": {"key1": "value1"},
|
||||
"field_2_key": {"key2": "value2"},
|
||||
}
|
||||
create_data_component.text_key = "key1"
|
||||
|
||||
# Act & Assert
|
||||
try:
|
||||
create_data_component.validate_text_key()
|
||||
except ValueError:
|
||||
pytest.fail("validate_text_key() raised ValueError unexpectedly!")
|
||||
|
||||
# Additional assertions
|
||||
assert create_data_component.text_key == "key1"
|
||||
assert "key1" in create_data_component.get_data()
|
||||
|
||||
|
||||
def test_validate_text_key_invalid(create_data_component):
|
||||
# Arrange
|
||||
create_data_component._attributes = {
|
||||
"field_1_key": {"key1": "value1"},
|
||||
"field_2_key": {"key2": "value2"},
|
||||
}
|
||||
create_data_component.text_key = "invalid_key"
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
create_data_component.validate_text_key()
|
||||
|
||||
# Check for the exact error message
|
||||
expected_error_message = f"Text Key: '{create_data_component.text_key}' not found in the Data keys: '{', '.join(create_data_component.get_data().keys())}'"
|
||||
assert str(exc_info.value) == expected_error_message
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import pytest
|
||||
from langflow.components.prototypes.UpdateData import UpdateDataComponent
|
||||
from langflow.schema import Data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def update_data_component():
|
||||
return UpdateDataComponent()
|
||||
|
||||
|
||||
def test_update_build_config(update_data_component):
|
||||
build_config = {
|
||||
"number_of_fields": {
|
||||
"type": "int",
|
||||
"value": 2,
|
||||
},
|
||||
"text_key": {
|
||||
"type": "str",
|
||||
"value": "",
|
||||
},
|
||||
"text_key_validator": {
|
||||
"type": "bool",
|
||||
"value": False,
|
||||
},
|
||||
}
|
||||
updated_config = update_data_component.update_build_config(
|
||||
build_config=build_config, field_value=3, field_name="number_of_fields"
|
||||
)
|
||||
|
||||
assert "field_1_key" in updated_config
|
||||
assert "field_2_key" in updated_config
|
||||
assert "field_3_key" in updated_config
|
||||
assert updated_config["number_of_fields"]["value"] == 3
|
||||
|
||||
|
||||
def test_update_build_config_exceed_limit(update_data_component):
|
||||
build_config = {
|
||||
"number_of_fields": {
|
||||
"type": "int",
|
||||
"value": 2,
|
||||
},
|
||||
"text_key": {
|
||||
"type": "str",
|
||||
"value": "",
|
||||
},
|
||||
"text_key_validator": {
|
||||
"type": "bool",
|
||||
"value": False,
|
||||
},
|
||||
}
|
||||
with pytest.raises(
|
||||
ValueError, match="Number of fields cannot exceed 15. Try using a Component to combine two Data."
|
||||
):
|
||||
update_data_component.update_build_config(build_config, 16, "number_of_fields")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_data(update_data_component):
|
||||
update_data_component._attributes = {
|
||||
"field_1_key": {"key1": "new_value1"},
|
||||
"field_2_key": {"key3": "value3"},
|
||||
}
|
||||
update_data_component.text_key = "key1"
|
||||
update_data_component.text_key_validator = False
|
||||
update_data_component.old_data = Data(data={"key1": "old_value1", "key2": "value2"}, text_key="key2")
|
||||
|
||||
result = await update_data_component.build_data()
|
||||
|
||||
assert isinstance(result, Data)
|
||||
assert result.data == {"key1": "new_value1", "key2": "value2", "key3": "value3"}
|
||||
assert result.text_key == "key1"
|
||||
|
||||
|
||||
def test_get_data(update_data_component):
|
||||
update_data_component._attributes = {
|
||||
"field_1_key": {"key1": "value1"},
|
||||
"field_2_key": {"key2": "value2"},
|
||||
}
|
||||
|
||||
result = update_data_component.get_data()
|
||||
|
||||
assert result == {"key1": "value1", "key2": "value2"}
|
||||
|
||||
|
||||
def test_validate_text_key_valid(update_data_component):
|
||||
data = Data(data={"key1": "value1", "key2": "value2"}, text_key="key1")
|
||||
update_data_component.text_key = "key1"
|
||||
|
||||
try:
|
||||
update_data_component.validate_text_key(data)
|
||||
except ValueError:
|
||||
pytest.fail("validate_text_key() raised ValueError unexpectedly!")
|
||||
|
||||
|
||||
def test_validate_text_key_invalid(update_data_component):
|
||||
data = Data(data={"key1": "value1", "key2": "value2"}, text_key="key1")
|
||||
update_data_component.text_key = "invalid_key"
|
||||
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
update_data_component.validate_text_key(data)
|
||||
|
||||
expected_error_message = (
|
||||
f"Text Key: {update_data_component.text_key} not found in the Data keys: {','.join(data.data.keys())}"
|
||||
)
|
||||
assert str(exc_info.value) == expected_error_message
|
||||
Loading…
Add table
Add a link
Reference in a new issue