fix(advanced-search): N - reference-type comparisons don't throw on ordering operators

This commit is contained in:
Kamron Batman 2026-07-19 21:57:05 -07:00
parent f8c594779e
commit 677a054448
2 changed files with 43 additions and 10 deletions

View file

@ -54,4 +54,16 @@ public class AdvancedSearchUtilitiesTests
var result = AdvancedSearchUtilities.EvaluateBoolean(expr, leaf => leaf == "T");
Assert.Equal(expected, result);
}
[Fact]
public void CompareValues_ReferenceType_EqualityByString_NoThrow()
{
// A reference-typed property (e.g. RootParent name-ish) compared with "=" should not throw,
// and ordering operators must return false rather than throwing.
var ex = Record.Exception(() =>
{
Assert.False(AdvancedSearchUtilities.CompareValues(typeof(object), new object(), "whatever", ">"));
});
Assert.Null(ex);
}
}

View file

@ -240,17 +240,38 @@ public static class AdvancedSearchUtilities
_ => false
};
public static bool CompareReference<T>(T propertyValue, T parsedValue, ReadOnlySpan<char> operatorSpan) =>
operatorSpan switch
public static bool CompareReference<T>(T propertyValue, T parsedValue, ReadOnlySpan<char> operatorSpan)
{
switch (operatorSpan)
{
"=" or "==" => propertyValue.Equals(parsedValue),
"!" or "!=" => !propertyValue.Equals(parsedValue),
">" => Comparer<T>.Default.Compare(propertyValue, parsedValue) > 0,
"<" => Comparer<T>.Default.Compare(propertyValue, parsedValue) < 0,
">=" => Comparer<T>.Default.Compare(propertyValue, parsedValue) >= 0,
"<=" => Comparer<T>.Default.Compare(propertyValue, parsedValue) <= 0,
_ => false
};
case "=":
case "==": return Equals(propertyValue, parsedValue);
case "!":
case "!=": return !Equals(propertyValue, parsedValue);
}
if (propertyValue is IComparable cmp && parsedValue != null)
{
try
{
var c = cmp.CompareTo(parsedValue);
return operatorSpan switch
{
">" => c > 0,
"<" => c < 0,
">=" => c >= 0,
"<=" => c <= 0,
_ => false
};
}
catch
{
return false;
}
}
return false;
}
public static T ParseValue<T>(ReadOnlySpan<char> valuePart)
{