fix(advanced-search): N - reference-type comparisons don't throw on ordering operators
This commit is contained in:
parent
f8c594779e
commit
677a054448
2 changed files with 43 additions and 10 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue