diff --git a/pytest_unordered/__init__.py b/pytest_unordered/__init__.py index 11da551..d2250db 100644 --- a/pytest_unordered/__init__.py +++ b/pytest_unordered/__init__.py @@ -67,6 +67,14 @@ def unordered(*args: Any, check_type: Optional[bool] = None) -> UnorderedList: return UnorderedList(args, check_type=False) +def unordered_deep(obj: Any) -> Any: + if isinstance(obj, dict): + return dict((k, unordered_deep(v)) for k, v in obj.items()) + if isinstance(obj, list) or isinstance(obj, tuple): + return unordered((unordered_deep(x) for x in obj)) + return obj + + def _compare_eq_unordered(left: Iterable, right: Iterable) -> Tuple[List, List]: extra_left = [] extra_right = list(right) diff --git a/tests/test_unordered.py b/tests/test_unordered.py index 4de3ff0..5974813 100644 --- a/tests/test_unordered.py +++ b/tests/test_unordered.py @@ -12,6 +12,7 @@ from pytest_unordered import UnorderedList from pytest_unordered import _compare_eq_unordered from pytest_unordered import unordered +from pytest_unordered import unordered_deep @pytest.mark.parametrize( @@ -255,3 +256,21 @@ def test_mock_any() -> None: assert p_unordered == test_1 assert p_unordered == test_2 assert p_unordered == test_3 + + +@pytest.mark.parametrize( + ["expected", "actual"], + [ + (unordered_deep([1, 2, 3]), [3, 2, 1]), + (unordered_deep((1, 2, 3)), (3, 2, 1)), + (unordered_deep({1, 2, 3}), {3, 2, 1}), + (unordered_deep([1, 2, {"a": (4, 5, 6)}]), [{"a": [6, 5, 4]}, 2, 1]), # fmt: skip + (unordered_deep([{1: (["a", "b"])}, 2, 3]), [3, 2, {1: ["b", "a"]}]), # fmt: skip + (unordered_deep(("a", "b", "c")), ["b", "a", "c"]), + ], +) +def test_unordered_deep(expected: UnorderedList, actual: Iterable) -> None: + assert expected == actual + assert actual == expected + assert not (expected != actual) + assert not (actual != expected)