153 lines
4.4 KiB
Python
153 lines
4.4 KiB
Python
from src.core.utils import FilterConf, SortConf, sort_by
|
|
from src.core.Expando import Expando
|
|
|
|
|
|
def test_i_can_sort_by_ascending_strings():
|
|
"""Test sorting strings in ascending order."""
|
|
items = [
|
|
Expando({"name": "charlie"}),
|
|
Expando({"name": "alice"}),
|
|
Expando({"name": "bob"})
|
|
]
|
|
sort_conf = SortConf(property="name", ascending=True)
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
assert result[0].name == "alice"
|
|
assert result[1].name == "bob"
|
|
assert result[2].name == "charlie"
|
|
|
|
|
|
def test_i_can_sort_by_descending_strings():
|
|
"""Test sorting strings in descending order."""
|
|
items = [
|
|
Expando({"name": "alice"}),
|
|
Expando({"name": "charlie"}),
|
|
Expando({"name": "bob"})
|
|
]
|
|
sort_conf = SortConf(property="name", ascending=False)
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
assert result[0].name == "charlie"
|
|
assert result[1].name == "bob"
|
|
assert result[2].name == "alice"
|
|
|
|
|
|
def test_i_can_handle_none_sort_conf():
|
|
"""Test that None sort configuration returns items unchanged."""
|
|
items = [
|
|
Expando({"name": "charlie"}),
|
|
Expando({"name": "alice"})
|
|
]
|
|
|
|
result = sort_by(items, None)
|
|
|
|
assert result == items
|
|
assert result[0].name == "charlie"
|
|
assert result[1].name == "alice"
|
|
|
|
|
|
def test_i_can_handle_empty_list():
|
|
"""Test that empty list returns empty list."""
|
|
items = []
|
|
sort_conf = SortConf(property="name")
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert result == []
|
|
|
|
|
|
def test_i_can_sort_with_missing_properties():
|
|
"""Test sorting when some objects don't have the property."""
|
|
items = [
|
|
Expando({"name": "bob"}),
|
|
Expando({"age": 25}), # no name property
|
|
Expando({"name": "alice"})
|
|
]
|
|
sort_conf = SortConf(property="name", ascending=True)
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
# Items without the property should get empty string and sort first
|
|
assert result[0].geti("name", "") == "" # the one with missing property
|
|
assert result[1].name == "alice"
|
|
assert result[2].name == "bob"
|
|
|
|
|
|
def test_i_can_sort_with_none_values():
|
|
"""Test sorting when properties have None values."""
|
|
items = [
|
|
Expando({"name": "bob"}),
|
|
Expando({"name": None}),
|
|
Expando({"name": "alice"})
|
|
]
|
|
sort_conf = SortConf(property="name", ascending=True)
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
# None values should be treated as empty strings and sort first
|
|
assert result[0].name is None
|
|
assert result[1].name == "alice"
|
|
assert result[2].name == "bob"
|
|
|
|
|
|
def test_i_can_sort_with_case_insensitive_property_names():
|
|
"""Test sorting using case-insensitive property names."""
|
|
items = [
|
|
Expando({"Name": "charlie"}), # uppercase N
|
|
Expando({"Name": "alice"}),
|
|
Expando({"Name": "bob"})
|
|
]
|
|
sort_conf = SortConf(property="name", ascending=True) # lowercase n
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
assert result[0].Name == "alice"
|
|
assert result[1].Name == "bob"
|
|
assert result[2].Name == "charlie"
|
|
|
|
|
|
|
|
def test_i_can_sort_mixed_types():
|
|
"""Test sorting with mixed types (numbers, strings, None)."""
|
|
items = [
|
|
Expando({"value": "zebra"}),
|
|
Expando({"value": 10}),
|
|
Expando({"value": None}),
|
|
Expando({"value": "apple"})
|
|
]
|
|
sort_conf = SortConf(property="value", ascending=True)
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 4
|
|
# Mixed types will be converted to strings for comparison
|
|
# None -> "", numbers -> str(number), strings stay strings
|
|
assert result[0].value is None # None becomes "" and sorts first
|
|
assert result[1].value == 10 # "10" sorts before "apple"
|
|
assert result[2].value == "apple" # "apple" sorts before "zebra"
|
|
assert result[3].value == "zebra"
|
|
|
|
|
|
def test_i_can_sort_with_whitespace_in_property_name():
|
|
"""Test that property names are stripped of whitespace."""
|
|
items = [
|
|
Expando({"name": "charlie"}),
|
|
Expando({"name": "alice"}),
|
|
Expando({"name": "bob"})
|
|
]
|
|
sort_conf = SortConf(property=" name ", ascending=True) # whitespace around property
|
|
|
|
result = sort_by(items, sort_conf)
|
|
|
|
assert len(result) == 3
|
|
assert result[0].name == "alice"
|
|
assert result[1].name == "bob"
|
|
assert result[2].name == "charlie"
|