feat: Improve data handling and text formatting (loop fix) (#6771)
* 📝 (loop.py): Improve code readability and semantics by updating the return condition in the LoopComponent class 📝 (data.py): Enhance the data_to_text_list function to handle various data structures and ensure consistent text formatting 📝 (LoopTemplate.json): Update the LoopComponent class description and method implementations for better clarity and maintainability 📝 (test_data_to_text_list.py): Add unit tests to cover different scenarios and edge cases for the data_to_text_list function * [autofix.ci] apply automated fixes * 📝 (langflow): Add noqa comments to ignore linting rule A005 for specific files in the project. Fix type annotations and improve error handling in data.py module. Add noqa comments to ignore linting rule A005 for specific files in the project. * ✅ (test_data_to_text_list.py): update parameter names in pytest.mark.parametrize to improve readability and maintainability * 🐛 (data.py): refactor error message handling in data_to_text_list function to improve readability and maintainability * [autofix.ci] apply automated fixes * Update src/backend/base/langflow/helpers/data.py Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * ♻️ (data.py): refactor data_to_text_list function to simplify the logic and improve readability by removing unnecessary if conditions and updating the format_dict directly from data_obj.data. * ✅ (test_data.py): refactor test_data_to_text_list function to handle defaultdict behavior and improve test coverage * ✅ (loop-component.spec.ts): update test expectation to match the correct number of occurrences of "modified_value" in the output * ✅ (Memory Chatbot.spec.ts): add assertion to check if the concatenated text length is greater than 20 to ensure the chatbot response is meaningful --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
05935ed2f3
commit
7b85505117
7 changed files with 217 additions and 32 deletions
|
|
@ -88,16 +88,18 @@ def test_data_to_text_list__template_wrong_placeholder():
|
|||
template = "My favorite color is {color}"
|
||||
data = Data(data={"fruit": "apple"})
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
data_to_text_list(template, data)
|
||||
# Should not raise KeyError due to defaultdict behavior
|
||||
result = data_to_text_list(template, data)
|
||||
assert result == (["My favorite color is "], [data])
|
||||
|
||||
|
||||
def test_data_to_text_list__data_with_data_attribute_empty():
|
||||
template = "My favorite color is {color}"
|
||||
data = Data(data={})
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
data_to_text_list(template, data)
|
||||
# Should not raise KeyError due to defaultdict behavior
|
||||
result = data_to_text_list(template, data)
|
||||
assert result == (["My favorite color is "], [data])
|
||||
|
||||
|
||||
def test_data_to_text_list__data_contains_nested_data_key():
|
||||
|
|
|
|||
134
src/backend/tests/unit/helpers/test_data_to_text_list.py
Normal file
134
src/backend/tests/unit/helpers/test_data_to_text_list.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
import pytest
|
||||
from langflow.helpers.data import data_to_text_list
|
||||
from langflow.schema import Data
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("template", "data", "expected_text"),
|
||||
[
|
||||
# Test basic string data
|
||||
(
|
||||
"Text: {text}",
|
||||
Data(text="Hello"),
|
||||
["Text: Hello"],
|
||||
),
|
||||
# Test dictionary data
|
||||
(
|
||||
"{name} is {age} years old",
|
||||
Data(data={"name": "Alice", "age": 25}),
|
||||
["Alice is 25 years old"],
|
||||
),
|
||||
# Test list of Data objects
|
||||
(
|
||||
"{name} is {age} years old",
|
||||
[
|
||||
Data(data={"name": "Alice", "age": 25}),
|
||||
Data(data={"name": "Bob", "age": 30}),
|
||||
],
|
||||
["Alice is 25 years old", "Bob is 30 years old"],
|
||||
),
|
||||
# Test nested data dictionary
|
||||
(
|
||||
"User: {text}",
|
||||
Data(data={"data": {"text": "Hello World"}}),
|
||||
["User: Hello World"],
|
||||
),
|
||||
# Test error message in data
|
||||
(
|
||||
"Error: {text}",
|
||||
Data(data={"error": "Something went wrong"}),
|
||||
["Error: Something went wrong"],
|
||||
),
|
||||
# Test non-Data object conversion
|
||||
(
|
||||
"Value: {text}",
|
||||
Data(text="Simple string"),
|
||||
["Value: Simple string"],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_data_to_text_list_parametrized(template, data, expected_text):
|
||||
"""Test various input combinations for data_to_text_list."""
|
||||
result = data_to_text_list(template, data)
|
||||
assert result[0] == expected_text
|
||||
assert all(isinstance(d, Data) for d in result[1])
|
||||
|
||||
|
||||
def test_data_to_text_list_none_data():
|
||||
"""Test handling of None data input."""
|
||||
result = data_to_text_list("template", None)
|
||||
assert result == ([], [])
|
||||
|
||||
|
||||
def test_data_to_text_list_none_template():
|
||||
"""Test handling of None template input."""
|
||||
with pytest.raises(ValueError, match="Template must be a string, but got None"):
|
||||
data_to_text_list(None, Data(text="test"))
|
||||
|
||||
|
||||
def test_data_to_text_list_invalid_template_type():
|
||||
"""Test handling of invalid template type."""
|
||||
with pytest.raises(TypeError, match="Template must be a string, but got"):
|
||||
data_to_text_list(123, Data(text="test"))
|
||||
|
||||
|
||||
def test_data_to_text_list_missing_key():
|
||||
"""Test handling of missing template key."""
|
||||
template = "Hello {missing_key}"
|
||||
data = Data(data={"existing_key": "value"})
|
||||
# Should not raise KeyError due to defaultdict
|
||||
result = data_to_text_list(template, data)
|
||||
assert result == (["Hello "], [data])
|
||||
|
||||
|
||||
def test_data_to_text_list_empty_data_dict():
|
||||
"""Test handling of empty data dictionary."""
|
||||
template = "Hello {text}"
|
||||
data = Data(data={})
|
||||
result = data_to_text_list(template, data)
|
||||
assert result == (["Hello "], [data])
|
||||
|
||||
|
||||
def test_data_to_text_list_mixed_data_types():
|
||||
"""Test handling of mixed data types in list."""
|
||||
template = "Item: {text}"
|
||||
data = [
|
||||
Data(text="First"),
|
||||
"Second",
|
||||
Data(data={"text": "Third"}),
|
||||
123,
|
||||
]
|
||||
result = data_to_text_list(template, data)
|
||||
expected_texts = [
|
||||
"Item: First",
|
||||
"Item: Second",
|
||||
"Item: Third",
|
||||
"Item: 123",
|
||||
]
|
||||
assert result[0] == expected_texts
|
||||
assert len(result[1]) == 4
|
||||
assert all(isinstance(d, Data) for d in result[1])
|
||||
|
||||
|
||||
def test_data_to_text_list_complex_nested_data():
|
||||
"""Test handling of complex nested data structures."""
|
||||
template = "Name: {name}, Info: {text}, Status: {status}"
|
||||
data = Data(data={"name": "Test", "data": {"text": "Nested text", "status": "active"}})
|
||||
result = data_to_text_list(template, data)
|
||||
expected = (["Name: Test, Info: Nested text, Status: active"], [data])
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_data_to_text_list_empty_template():
|
||||
"""Test handling of empty template string."""
|
||||
data = Data(data={"key": "value"})
|
||||
result = data_to_text_list("", data)
|
||||
assert result == ([""], [data])
|
||||
|
||||
|
||||
def test_data_to_text_list_string_data():
|
||||
"""Test handling of string data in Data object."""
|
||||
template = "Message: {text}"
|
||||
data = Data(data={"text": "Direct string"})
|
||||
result = data_to_text_list(template, data)
|
||||
assert result == (["Message: Direct string"], [data])
|
||||
Loading…
Add table
Add a link
Reference in a new issue