"""Tests for utilities.""" from dataclasses import dataclass from operator import attrgetter import pytest from src.utils import has_duplicates @dataclass(frozen=True) class Item: """Simple dataclass for testing.""" id: int value: str @pytest.mark.parametrize( 'items, key, expected', [ # --- Case 1: key is None (checking the items themselves) --- pytest.param([1, 2, 3, 4, 2], None, True, id='key_is_none_with_duplicates'), pytest.param([1, 2, 3, 4, 5], None, False, id='key_is_none_no_duplicates'), pytest.param([], None, False, id='key_is_none_empty_list'), pytest.param(('a', 'b', 'c', 'a'), None, True, id='key_is_none_tuple_with_duplicates'), # --- Case 2: key is a string (for dicts) --- pytest.param( [{'id': 1, 'val': 'a'}, {'id': 2, 'val': 'b'}, {'id': 1, 'val': 'c'}], 'id', True, id='key_is_string_with_duplicates', ), pytest.param( [{'id': 1, 'val': 'a'}, {'id': 2, 'val': 'b'}, {'id': 3, 'val': 'c'}], 'id', False, id='key_is_string_no_duplicates', ), # --- Case 3: key is a callable (lambda or attrgetter) --- pytest.param( [Item(1, 'a'), Item(2, 'b'), Item(1, 'c')], attrgetter('id'), True, id='key_is_callable_with_duplicates' ), pytest.param( [Item(1, 'a'), Item(2, 'b'), Item(3, 'c')], attrgetter('id'), False, id='key_is_callable_no_duplicates' ), pytest.param(['apple', 'banana', 'kiwi', 'pear'], len, True, id='key_is_callable_len_function'), ], ) def test_has_duplicates(items, key, expected): """Tests the has_duplicates utility with various inputs and key types.""" assert has_duplicates(items, key=key) == expected