@@ -796,4 +796,199 @@ public void can_filter_with_has_conversion_configuration()
796796 expressionString . Should ( ) . Contain ( "x.Email" ) ;
797797 expressionString . Should ( ) . Contain ( "test@example.com" ) ;
798798 }
799+
800+ [ Fact ]
801+ public void case_insensitive_default_config_uses_to_lower ( )
802+ {
803+ // Arrange - no config, should default to ToLower
804+ var input = """Title @=* "waffle" """ ;
805+
806+ // Act
807+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input ) ;
808+
809+ // Assert
810+ filterExpression . ToString ( ) . Should ( )
811+ . Be ( """x => ((x.Title != null) AndAlso x.Title.ToLower().Contains("waffle".ToLower()))""" ) ;
812+ }
813+
814+ [ Fact ]
815+ public void case_insensitive_upper_mode_global_uses_to_upper ( )
816+ {
817+ // Arrange - global Upper mode
818+ var input = """Title @=* "waffle" """ ;
819+ var config = new QueryKitConfiguration ( settings =>
820+ {
821+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
822+ } ) ;
823+
824+ // Act
825+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
826+
827+ // Assert - should use ToUpper instead of ToLower
828+ filterExpression . ToString ( ) . Should ( )
829+ . Be ( """x => ((x.Title != null) AndAlso x.Title.ToUpper().Contains("waffle".ToUpper()))""" ) ;
830+ }
831+
832+ [ Fact ]
833+ public void case_insensitive_per_property_upper_mode_overrides_global_lower ( )
834+ {
835+ // Arrange - global Lower (default), per-property Title set to Upper
836+ var input = """Title @=* "waffle" """ ;
837+ var config = new QueryKitConfiguration ( settings =>
838+ {
839+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Lower ;
840+ settings . Property < TestingPerson > ( x => x . Title ) . HasCaseInsensitiveMode ( CaseInsensitiveMode . Upper ) ;
841+ } ) ;
842+
843+ // Act
844+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
845+
846+ // Assert - Title should use ToUpper because of per-property override
847+ filterExpression . ToString ( ) . Should ( )
848+ . Be ( """x => ((x.Title != null) AndAlso x.Title.ToUpper().Contains("waffle".ToUpper()))""" ) ;
849+ }
850+
851+ [ Fact ]
852+ public void case_insensitive_equals_upper_mode_uses_to_upper ( )
853+ {
854+ // Arrange
855+ var input = """Title ==* "waffle" """ ;
856+ var config = new QueryKitConfiguration ( settings =>
857+ {
858+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
859+ } ) ;
860+
861+ // Act
862+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
863+
864+ // Assert
865+ filterExpression . ToString ( ) . Should ( )
866+ . Contain ( "ToUpper" ) ;
867+ filterExpression . ToString ( ) . Should ( )
868+ . NotContain ( "ToLower" ) ;
869+ }
870+
871+ [ Fact ]
872+ public void case_insensitive_not_equals_upper_mode_uses_to_upper ( )
873+ {
874+ var input = """Title !=* "lamb" """ ;
875+ var config = new QueryKitConfiguration ( settings =>
876+ {
877+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
878+ } ) ;
879+
880+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
881+
882+ filterExpression . ToString ( ) . Should ( )
883+ . Be ( "x => ((x.Title == null) OrElse (x.Title.ToUpper() != \" lamb\" .ToUpper()))" ) ;
884+ }
885+
886+ [ Fact ]
887+ public void case_insensitive_starts_with_upper_mode_uses_to_upper ( )
888+ {
889+ var input = """Title _=* "lamb" """ ;
890+ var config = new QueryKitConfiguration ( settings =>
891+ {
892+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
893+ } ) ;
894+
895+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
896+
897+ filterExpression . ToString ( ) . Should ( )
898+ . Be ( "x => ((x.Title != null) AndAlso x.Title.ToUpper().StartsWith(\" lamb\" .ToUpper()))" ) ;
899+ }
900+
901+ [ Fact ]
902+ public void case_insensitive_ends_with_upper_mode_uses_to_upper ( )
903+ {
904+ var input = """Title _-=* "lamb" """ ;
905+ var config = new QueryKitConfiguration ( settings =>
906+ {
907+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
908+ } ) ;
909+
910+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
911+
912+ filterExpression . ToString ( ) . Should ( )
913+ . Be ( "x => ((x.Title != null) AndAlso x.Title.ToUpper().EndsWith(\" lamb\" .ToUpper()))" ) ;
914+ }
915+
916+ [ Fact ]
917+ public void case_insensitive_not_contains_upper_mode_uses_to_upper ( )
918+ {
919+ var input = """Title !@=* "lamb" """ ;
920+ var config = new QueryKitConfiguration ( settings =>
921+ {
922+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
923+ } ) ;
924+
925+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
926+
927+ filterExpression . ToString ( ) . Should ( )
928+ . Be ( "x => ((x.Title == null) OrElse Not(x.Title.ToUpper().Contains(\" lamb\" .ToUpper())))" ) ;
929+ }
930+
931+ [ Fact ]
932+ public void case_insensitive_not_starts_with_upper_mode_uses_to_upper ( )
933+ {
934+ var input = """Title !_=* "lamb" """ ;
935+ var config = new QueryKitConfiguration ( settings =>
936+ {
937+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
938+ } ) ;
939+
940+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
941+
942+ filterExpression . ToString ( ) . Should ( )
943+ . Be ( "x => ((x.Title == null) OrElse Not(x.Title.ToUpper().StartsWith(\" lamb\" .ToUpper())))" ) ;
944+ }
945+
946+ [ Fact ]
947+ public void case_insensitive_not_ends_with_upper_mode_uses_to_upper ( )
948+ {
949+ var input = """Title !_-=* "lamb" """ ;
950+ var config = new QueryKitConfiguration ( settings =>
951+ {
952+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
953+ } ) ;
954+
955+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
956+
957+ filterExpression . ToString ( ) . Should ( )
958+ . Be ( "x => ((x.Title == null) OrElse Not(x.Title.ToUpper().EndsWith(\" lamb\" .ToUpper())))" ) ;
959+ }
960+
961+ [ Fact ]
962+ public void case_insensitive_in_operator_upper_mode_uses_to_upper ( )
963+ {
964+ var input = """Title ^^* ["lamb","chicken"] """ ;
965+ var config = new QueryKitConfiguration ( settings =>
966+ {
967+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
968+ } ) ;
969+
970+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
971+ var asString = filterExpression . ToString ( ) ;
972+
973+ asString . Should ( ) . Contain ( "ToUpper" ) ;
974+ asString . Should ( ) . NotContain ( "ToLower" ) ;
975+ }
976+
977+ [ Fact ]
978+ public void case_insensitive_per_property_lower_overrides_global_upper ( )
979+ {
980+ // Arrange - global Upper, per-property Title set back to Lower
981+ var input = """Title @=* "waffle" """ ;
982+ var config = new QueryKitConfiguration ( settings =>
983+ {
984+ settings . CaseInsensitiveComparison = CaseInsensitiveMode . Upper ;
985+ settings . Property < TestingPerson > ( x => x . Title ) . HasCaseInsensitiveMode ( CaseInsensitiveMode . Lower ) ;
986+ } ) ;
987+
988+ var filterExpression = FilterParser . ParseFilter < TestingPerson > ( input , config ) ;
989+
990+ // Title should use ToLower because per-property overrides global Upper
991+ filterExpression . ToString ( ) . Should ( )
992+ . Be ( """x => ((x.Title != null) AndAlso x.Title.ToLower().Contains("waffle".ToLower()))""" ) ;
993+ }
799994}
0 commit comments