langflow/src/backend/tests/unit/components/processing/test_dataframe_operations.py
Rodrigo Nader 62c13adcfd
feat: add dataframe operations component (#5341)
* add dataframe operations component

* populate entire new column with value

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* Add unit tests for DataFrame operations in `test_dataframe_operations.py`

* **Import modules**
  - Import `pytest` and `pandas` for testing DataFrame operations

* **Define test cases**
  - Define test cases for edge cases like empty DataFrames and invalid column names
  - Include tests for operations like "Head", "Tail", and "Replace Value"
  - Use `pytest.mark.parametrize` to test multiple operations with different inputs
  - Add detailed assertions to verify the correctness of DataFrame operations

* [autofix.ci] apply automated fixes

* Remove test cases for DataFrame operations from `test_dataframe_operations.py`. This deletion includes all unit tests related to various DataFrame operations such as adding, dropping, filtering, and renaming columns, as well as handling edge cases like empty DataFrames and invalid operations. The removal streamlines the test suite by eliminating outdated or redundant tests.

* Add unit tests for DataFrame operations in

- Introduced a new test file  for organizing test components.
- Updated import paths for  to reflect the new module structure.
- Refactored test cases to use  for better readability and maintainability.
- Enhanced assertions in tests for various DataFrame operations, including handling of empty DataFrames and invalid operations.
- Improved code formatting for consistency and clarity.

* Refactor DataFrameOperationsComponent for improved readability and maintainability

- Consolidated import statements for clarity.
- Renamed variable `df` to `dataframe_copy` for better understanding.
- Streamlined the `perform_operation` method by replacing `elif` with `if` statements for clearer logic flow.
- Enhanced error message for unsupported operations to improve debugging.

These changes aim to enhance the code structure and make future modifications easier.

* Update unit tests for DataFrame operations in `test_dataframe_operations.py`

- Modified expected values in parameterized tests for various DataFrame operations, including "Add Column", "Filter", "Sort", "Head", "Tail", and "Replace Value" to reflect new test scenarios.
- Adjusted assertions to ensure they correctly validate the output of operations, particularly for lists of expected values.
- Enhanced error handling in the test for invalid operations to provide clearer feedback on unsupported operation types.

These changes improve the accuracy and robustness of the unit tests for DataFrame operations.

* Refactor DataFrameOperationsComponent methods to return DataFrame instances consistently

---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2024-12-19 16:14:04 +00:00

84 lines
2.8 KiB
Python

import pandas as pd
import pytest
from langflow.components.processing.dataframe_operations import DataFrameOperationsComponent
@pytest.fixture
def sample_dataframe():
data = {"A": [1, 2, 3, 4, 5], "B": [5, 4, 3, 2, 1], "C": ["a", "b", "c", "d", "e"]}
return pd.DataFrame(data)
@pytest.mark.parametrize(
("operation", "expected_columns", "expected_values"),
[
("Add Column", ["A", "B", "C", "D"], [1, 5, "a", 10]),
("Drop Column", ["A", "C"], None),
("Filter", ["A", "B", "C"], [3, 3, "c"]),
("Sort", ["A", "B", "C"], [5, 1, "e"]),
("Rename Column", ["Z", "B", "C"], None),
("Select Columns", ["A", "C"], None),
("Head", ["A", "B", "C"], [1, 5, "a"]),
("Tail", ["A", "B", "C"], [5, 1, "e"]),
("Replace Value", ["A", "B", "C"], [1, 5, "z"]),
],
)
def test_operations(sample_dataframe, operation, expected_columns, expected_values):
component = DataFrameOperationsComponent()
component.df = sample_dataframe
component.operation = operation
if operation == "Add Column":
component.new_column_name = "D"
component.new_column_value = 10
elif operation == "Drop Column":
component.column_name = "B"
elif operation == "Filter":
component.column_name = "A"
component.filter_value = 3
elif operation == "Sort":
component.column_name = "A"
component.ascending = False
elif operation == "Rename Column":
component.column_name = "A"
component.new_column_name = "Z"
elif operation == "Select Columns":
component.columns_to_select = ["A", "C"]
elif operation in ("Head", "Tail"):
component.num_rows = 1
elif operation == "Replace Value":
component.column_name = "C"
component.replace_value = "a"
component.replacement_value = "z"
result = component.perform_operation()
assert list(result.columns) == expected_columns
if expected_values is not None and isinstance(expected_values, list):
assert list(result.iloc[0]) == expected_values
def test_empty_dataframe():
component = DataFrameOperationsComponent()
component.df = pd.DataFrame()
component.operation = "Head"
component.num_rows = 3
result = component.perform_operation()
assert result.empty
def test_non_existent_column():
component = DataFrameOperationsComponent()
component.df = pd.DataFrame({"A": [1, 2, 3]})
component.operation = "Drop Column"
component.column_name = "B"
with pytest.raises(KeyError):
component.perform_operation()
def test_invalid_operation():
component = DataFrameOperationsComponent()
component.df = pd.DataFrame({"A": [1, 2, 3]})
component.operation = "Invalid Operation"
with pytest.raises(ValueError, match="Unsupported operation: Invalid Operation"):
component.perform_operation()