22
33import dataclasses
44import typing as t
5+ from collections .abc import Callable , Mapping
56from contextlib import suppress
67
78import pytest
@@ -416,30 +417,28 @@ def test_lookup_functions_additional_edge_cases() -> None:
416417 assert not lookup_in ("key" , {"key" : "value" }) # String in dict keys
417418 assert lookup_in ("item" , ["item" , "other" ]) # String in list
418419 assert not lookup_in ("missing" , {"key" : "value" }) # Missing key in dict
419- assert not lookup_in (123 , "123" ) # Invalid type combination
420+ assert not lookup_in (123 , "123" ) # type: ignore # Invalid type combination
420421
421422 # Test lookup_nin with various types
422- assert not lookup_nin (
423- "missing" , {"key" : "value" }
424- ) # Missing key in dict returns False
425- assert not lookup_nin (
426- "value" , {"key" : "value" }
427- ) # String in dict values returns False
423+ # Missing key in dict returns False
424+ assert not lookup_nin ("missing" , {"key" : "value" })
425+ # String in dict values returns False
426+ assert not lookup_nin ("value" , {"key" : "value" })
428427 assert lookup_nin ("item" , ["other" , "another" ]) # String not in list
429428 assert not lookup_nin ("item" , ["item" , "other" ]) # String in list
430- assert not lookup_nin (123 , "123" ) # Invalid type combination returns False
429+ assert not lookup_nin (123 , "123" ) # type: ignore # Invalid type combination returns False
431430
432431 # Test lookup_regex with various types
433432 assert lookup_regex ("test123" , r"\d+" ) # Match digits
434433 assert not lookup_regex ("test" , r"\d+" ) # No match
435- assert not lookup_regex (123 , r"\d+" ) # Invalid type
436- assert not lookup_regex ("test" , 123 ) # Invalid pattern type
434+ assert not lookup_regex (123 , r"\d+" ) # type: ignore # Invalid type
435+ assert not lookup_regex ("test" , 123 ) # type: ignore # Invalid pattern type
437436
438437 # Test lookup_iregex with various types
439438 assert lookup_iregex ("TEST123" , r"test\d+" ) # Case-insensitive match
440439 assert not lookup_iregex ("test" , r"\d+" ) # No match
441- assert not lookup_iregex (123 , r"\d+" ) # Invalid type
442- assert not lookup_iregex ("test" , 123 ) # Invalid pattern type
440+ assert not lookup_iregex (123 , r"\d+" ) # type: ignore # Invalid type
441+ assert not lookup_iregex ("test" , 123 ) # type: ignore # Invalid pattern type
443442
444443
445444def test_query_list_items () -> None :
@@ -498,11 +497,11 @@ def get_id_2(x: dict[str, int]) -> bool:
498497 return x ["id" ] == 2
499498
500499 result = ql .get (get_id_2 )
501- assert result ["id" ] == 2
500+ assert result is not None and result ["id" ] == 2 # Check for None before indexing
502501
503502 # Test get with lambda
504503 result = ql .get (lambda x : x ["id" ] == 3 )
505- assert result ["id" ] == 3
504+ assert result is not None and result ["id" ] == 3 # Check for None before indexing
506505
507506 # Test get with callable returning multiple matches
508507 def get_id_greater_than_1 (x : dict [str , int ]) -> bool :
@@ -517,3 +516,106 @@ def get_id_greater_than_10(x: dict[str, int]) -> bool:
517516
518517 with pytest .raises (ObjectDoesNotExist ):
519518 ql .get (get_id_greater_than_10 )
519+
520+
521+ def test_query_list_eq_with_mappings () -> None :
522+ """Test QueryList __eq__ method with mappings."""
523+ # Test comparing mappings with numeric values
524+ ql1 = QueryList ([{"a" : 1 , "b" : 2 }])
525+ ql2 = QueryList ([{"a" : 1 , "b" : 2 }])
526+ assert ql1 == ql2
527+
528+ # Test comparing mappings with different values
529+ ql3 = QueryList ([{"a" : 1 , "b" : 3 }])
530+ assert ql1 != ql3
531+
532+ # Test comparing with non-list
533+ assert ql1 != "not a list"
534+
535+ # Test comparing mappings with different keys
536+ ql4 = QueryList ([{"a" : 1 , "c" : 2 }])
537+ assert ql1 != ql4
538+
539+ # Test comparing mappings with close numeric values (within tolerance)
540+ ql5 = QueryList ([{"a" : 1.0001 , "b" : 2.0001 }])
541+ assert ql1 == ql5 # Should be equal since difference is less than 1
542+
543+ # Test comparing mappings with different numeric values (outside tolerance)
544+ ql6 = QueryList ([{"a" : 2.5 , "b" : 3.5 }])
545+ assert ql1 != ql6 # Should not be equal since difference is more than 1
546+
547+
548+ def test_lookup_in_with_mappings () -> None :
549+ """Test lookup_in function with mappings."""
550+ # Test with string in mapping keys
551+ data : dict [str , str ] = {"key" : "value" , "other" : "value2" }
552+ assert not lookup_in ("missing" , data ) # Key not in mapping
553+ assert not lookup_in ("value" , data ) # Value not in mapping keys
554+ assert not lookup_in ("key" , data ) # Key in mapping but returns False
555+
556+ # Test with string in mapping values
557+ assert not lookup_in ("value" , data ) # Value in mapping but returns False
558+
559+ # Test with invalid combinations
560+ assert not lookup_in (123 , data ) # type: ignore # Invalid type for data
561+ assert not lookup_in ("key" , 123 ) # type: ignore # Invalid type for rhs
562+
563+ # Test with list in mapping
564+ data_list : list [str ] = ["value1" , "value2" ]
565+ assert lookup_in ("value1" , data_list ) # Value in list returns True
566+
567+
568+ def test_lookup_nin_with_mappings () -> None :
569+ """Test lookup_nin function with mappings."""
570+ # Test with string in mapping keys
571+ data : dict [str , str ] = {"key" : "value" , "other" : "value2" }
572+ assert not lookup_nin ("missing" , data ) # Key not in mapping returns False
573+ assert not lookup_nin ("value" , data ) # Value not in mapping keys returns False
574+ assert not lookup_nin ("key" , data ) # Key in mapping returns False
575+
576+ # Test with string in mapping values
577+ assert not lookup_nin ("value" , data ) # Value in mapping returns False
578+
579+ # Test with invalid combinations
580+ assert not lookup_nin (123 , data ) # type: ignore # Invalid type for data
581+ assert not lookup_nin ("key" , 123 ) # type: ignore # Invalid type for rhs
582+
583+ # Test with list in mapping
584+ data_list : list [str ] = ["value1" , "value2" ]
585+ assert not lookup_nin ("value1" , data_list ) # Value in list returns False
586+
587+
588+ def test_filter_error_handling () -> None :
589+ """Test error handling in filter method."""
590+ ql : QueryList [Mapping [str , t .Any ]] = QueryList ([{"id" : 1 }, {"id" : 2 }])
591+
592+ # Test with non-existent field
593+ result = ql .filter (nonexistent = 1 )
594+ assert len (result ) == 0
595+
596+ # Test with invalid lookup
597+ result = ql .filter (id__invalid = "test" )
598+ assert len (result ) == 0
599+
600+ # Test with multiple conditions where one is invalid
601+ result = ql .filter (id__exact = 1 , id__invalid = "test" )
602+ assert len (result ) == 0
603+
604+ # Test with non-string paths
605+ with pytest .raises (TypeError ):
606+ # We need to use Any here because we're intentionally testing invalid types
607+ numeric_key : t .Any = 123
608+ numeric_args : dict [t .Any , t .Any ] = {numeric_key : "test" }
609+ ql .filter (** numeric_args )
610+
611+ # Test with None path
612+ with pytest .raises (TypeError ):
613+ # We need to use Any here because we're intentionally testing invalid types
614+ none_key : t .Any = None
615+ none_args : dict [t .Any , t .Any ] = {none_key : "test" }
616+ ql .filter (** none_args )
617+
618+ # Test with empty path
619+ empty_args : dict [str , t .Any ] = {"" : "test" }
620+ result = ql .filter (** empty_args )
621+ assert len (result ) == 0
0 commit comments