diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f7ce7ac..4a4ae9bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# v1.7.1 (29 November 2025)
+- [#961](https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/961) - Fix Json when property value is null [bug] contributed by [StefH](https://github.com/StefH)
+- [#962](https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/962) - json: fix logic when property is not found [bug] contributed by [StefH](https://github.com/StefH)
+- [#965](https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/965) - Fix NumberParser for integer < int.MinValue [bug] contributed by [StefH](https://github.com/StefH)
+- [#960](https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/960) - json: follow up for not existing members [bug]
+- [#964](https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/964) - Integer numbers smaller than int.MinValue are not parsed correctly [bug]
+
# v1.7.0 (15 November 2025)
- [#956](https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/956) - Fix parsing Hex and Binary [bug] contributed by [StefH](https://github.com/StefH)
- [#957](https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/957) - .NET 10 [feature] contributed by [StefH](https://github.com/StefH)
diff --git a/Generate-ReleaseNotes.bat b/Generate-ReleaseNotes.bat
index 07a52300..809d22d8 100644
--- a/Generate-ReleaseNotes.bat
+++ b/Generate-ReleaseNotes.bat
@@ -1,5 +1,5 @@
rem https://github.com/StefH/GitHubReleaseNotes
-SET version=v1.7.0
+SET version=v1.7.1
GitHubReleaseNotes --output CHANGELOG.md --exclude-labels known_issue out_of_scope not_planned invalid question documentation wontfix environment duplicate --language en --version %version% --token %GH_TOKEN%
diff --git a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NewtonsoftJsonParsingConfig.cs b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NewtonsoftJsonParsingConfig.cs
index fbccbf64..3cb24306 100644
--- a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NewtonsoftJsonParsingConfig.cs
+++ b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NewtonsoftJsonParsingConfig.cs
@@ -10,7 +10,10 @@ public class NewtonsoftJsonParsingConfig : ParsingConfig
///
/// The default ParsingConfig for .
///
- public new static NewtonsoftJsonParsingConfig Default { get; } = new();
+ public new static NewtonsoftJsonParsingConfig Default { get; } = new NewtonsoftJsonParsingConfig
+ {
+ ConvertObjectToSupportComparison = true
+ };
///
/// The default to use.
@@ -28,7 +31,7 @@ public class NewtonsoftJsonParsingConfig : ParsingConfig
///
/// Use this property to control how the normalization process handles properties that are missing or undefined.
/// The selected behavior may affect the output or error handling of normalization operations.
- /// The default value is .
+ /// The default value is .
///
public NormalizationNonExistingPropertyBehavior NormalizationNonExistingPropertyValueBehavior { get; set; }
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NormalizationNonExistingPropertyBehavior.cs b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NormalizationNonExistingPropertyBehavior.cs
index bb68277b..44608e83 100644
--- a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NormalizationNonExistingPropertyBehavior.cs
+++ b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Config/NormalizationNonExistingPropertyBehavior.cs
@@ -6,12 +6,12 @@
public enum NormalizationNonExistingPropertyBehavior
{
///
- /// Specifies that the default value should be used.
+ /// Specifies that a null value should be used.
///
- UseDefaultValue = 0,
+ UseNull = 0,
///
- /// Specifies that null values should be used.
+ /// Specifies that the default value should be used.
///
- UseNull = 1
+ UseDefaultValue = 1
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Extensions/JObjectExtensions.cs b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Extensions/JObjectExtensions.cs
index 1a7be2f4..2f79840b 100644
--- a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Extensions/JObjectExtensions.cs
+++ b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Extensions/JObjectExtensions.cs
@@ -44,10 +44,7 @@ private class JTokenResolvers : Dictionary func)
private static IQueryable ToQueryable(JArray source, NewtonsoftJsonParsingConfig? config = null)
{
- var normalized = config?.Normalize == true ?
- NormalizeUtils.NormalizeArray(source, config.NormalizationNonExistingPropertyValueBehavior):
+ config = config ?? NewtonsoftJsonParsingConfig.Default;
+ config.ConvertObjectToSupportComparison = true;
+
+ var normalized = config.Normalize == true ?
+ NormalizeUtils.NormalizeArray(source, config.NormalizationNonExistingPropertyValueBehavior) :
source;
return normalized
diff --git a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Utils/NormalizeUtils.cs b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Utils/NormalizeUtils.cs
index 5669915c..fe980319 100644
--- a/src/System.Linq.Dynamic.Core.NewtonsoftJson/Utils/NormalizeUtils.cs
+++ b/src/System.Linq.Dynamic.Core.NewtonsoftJson/Utils/NormalizeUtils.cs
@@ -86,7 +86,7 @@ private static JObject NormalizeObject(JObject source, Dictionary schem
}
else
{
- obj[key] = normalizationBehavior == NormalizationNonExistingPropertyBehavior.UseDefaultValue ? GetDefaultValue(schema[key]) : JValue.CreateNull();
+ obj[key] = GetDefaultOrNullValue(normalizationBehavior, schema[key]);
}
}
@@ -125,7 +125,28 @@ private static JToken GetDefaultValue(JsonValueInfo jType)
JTokenType.Integer => default(int),
JTokenType.String => string.Empty,
JTokenType.TimeSpan => TimeSpan.MinValue,
+ _ => GetNullValue(jType),
+ };
+ }
+
+ private static JValue GetNullValue(JsonValueInfo jType)
+ {
+ return jType.Type switch
+ {
+ JTokenType.Boolean => new JValue((bool?)null),
+ JTokenType.Bytes => new JValue((byte[]?)null),
+ JTokenType.Date => new JValue((DateTime?)null),
+ JTokenType.Float => new JValue((float?)null),
+ JTokenType.Guid => new JValue((Guid?)null),
+ JTokenType.Integer => new JValue((int?)null),
+ JTokenType.String => new JValue((string?)null),
+ JTokenType.TimeSpan => new JValue((TimeSpan?)null),
_ => JValue.CreateNull(),
};
}
+
+ private static JToken GetDefaultOrNullValue(NormalizationNonExistingPropertyBehavior behavior, JsonValueInfo jType)
+ {
+ return behavior == NormalizationNonExistingPropertyBehavior.UseDefaultValue ? GetDefaultValue(jType) : GetNullValue(jType);
+ }
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core.SystemTextJson/Config/NormalizationNonExistingPropertyBehavior.cs b/src/System.Linq.Dynamic.Core.SystemTextJson/Config/NormalizationNonExistingPropertyBehavior.cs
index daafaa4b..381f0408 100644
--- a/src/System.Linq.Dynamic.Core.SystemTextJson/Config/NormalizationNonExistingPropertyBehavior.cs
+++ b/src/System.Linq.Dynamic.Core.SystemTextJson/Config/NormalizationNonExistingPropertyBehavior.cs
@@ -1,17 +1,17 @@
namespace System.Linq.Dynamic.Core.SystemTextJson.Config;
///
-/// Specifies the behavior to use when setting a property vlue that does not exist or is missing during normalization.
+/// Specifies the behavior to use when setting a property value that does not exist or is missing during normalization.
///
public enum NormalizationNonExistingPropertyBehavior
{
///
- /// Specifies that the default value should be used.
+ /// Specifies that a null value should be used.
///
- UseDefaultValue = 0,
+ UseNull = 0,
///
- /// Specifies that null values should be used.
+ /// Specifies that the default value should be used.
///
- UseNull = 1
+ UseDefaultValue = 1
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core.SystemTextJson/Config/SystemTextJsonParsingConfig.cs b/src/System.Linq.Dynamic.Core.SystemTextJson/Config/SystemTextJsonParsingConfig.cs
index a4c1e76a..4892bcf2 100644
--- a/src/System.Linq.Dynamic.Core.SystemTextJson/Config/SystemTextJsonParsingConfig.cs
+++ b/src/System.Linq.Dynamic.Core.SystemTextJson/Config/SystemTextJsonParsingConfig.cs
@@ -24,7 +24,7 @@ public class SystemTextJsonParsingConfig : ParsingConfig
///
/// Use this property to control how the normalization process handles properties that are missing or undefined.
/// The selected behavior may affect the output or error handling of normalization operations.
- /// The default value is .
+ /// The default value is .
///
public NormalizationNonExistingPropertyBehavior NormalizationNonExistingPropertyValueBehavior { get; set; }
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core.SystemTextJson/Extensions/JsonDocumentExtensions.cs b/src/System.Linq.Dynamic.Core.SystemTextJson/Extensions/JsonDocumentExtensions.cs
index 7daf15a5..3437d3c9 100644
--- a/src/System.Linq.Dynamic.Core.SystemTextJson/Extensions/JsonDocumentExtensions.cs
+++ b/src/System.Linq.Dynamic.Core.SystemTextJson/Extensions/JsonDocumentExtensions.cs
@@ -34,10 +34,7 @@ private class JTokenResolvers : Dictionary src, Type newType)
{
var method = ConvertToTypedArrayGenericMethod.MakeGenericMethod(newType);
- return (IEnumerable)method.Invoke(null, new object[] { src })!;
+ return (IEnumerable)method.Invoke(null, [src])!;
}
private static readonly MethodInfo ConvertToTypedArrayGenericMethod = typeof(JsonDocumentExtensions).GetMethod(nameof(ConvertToTypedArrayGeneric), BindingFlags.NonPublic | BindingFlags.Static)!;
diff --git a/src/System.Linq.Dynamic.Core.SystemTextJson/Utils/NormalizeUtils.cs b/src/System.Linq.Dynamic.Core.SystemTextJson/Utils/NormalizeUtils.cs
index fa5836d2..7f6e4abf 100644
--- a/src/System.Linq.Dynamic.Core.SystemTextJson/Utils/NormalizeUtils.cs
+++ b/src/System.Linq.Dynamic.Core.SystemTextJson/Utils/NormalizeUtils.cs
@@ -104,15 +104,16 @@ private static JsonObject NormalizeObject(JsonObject source, Dictionary sc
}
else
{
- obj[key] = normalizationBehavior == NormalizationNonExistingPropertyBehavior.UseDefaultValue ? GetDefaultValue(jType) : null;
+ obj[key] = GetDefaultOrNullValue(normalizationBehavior, jType);
}
}
@@ -150,7 +151,25 @@ private static JsonObject CreateEmptyObject(Dictionary sc
JsonValueKind.Number => default(int),
JsonValueKind.String => string.Empty,
JsonValueKind.True => false,
+ _ => GetNullValue(jType),
+ };
+ }
+
+ private static JsonNode? GetNullValue(JsonValueInfo jType)
+ {
+ return jType.Type switch
+ {
+ JsonValueKind.Array => null,
+ JsonValueKind.False => JsonValue.Create(false),
+ JsonValueKind.Number => JsonValue.Create(null),
+ JsonValueKind.String => JsonValue.Create(null),
+ JsonValueKind.True => JsonValue.Create(true),
_ => null,
};
}
+
+ private static JsonNode? GetDefaultOrNullValue(NormalizationNonExistingPropertyBehavior behavior, JsonValueInfo jType)
+ {
+ return behavior == NormalizationNonExistingPropertyBehavior.UseDefaultValue ? GetDefaultValue(jType) : GetNullValue(jType);
+ }
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/DynamicClass.cs b/src/System.Linq.Dynamic.Core/DynamicClass.cs
index 33f06aee..64685f5e 100644
--- a/src/System.Linq.Dynamic.Core/DynamicClass.cs
+++ b/src/System.Linq.Dynamic.Core/DynamicClass.cs
@@ -123,6 +123,16 @@ public object? this[string name]
}
}
+ ///
+ /// Determines whether a property with the specified name exists in the collection.
+ ///
+ /// The name of the property to locate. Cannot be null.
+ /// true if a property with the specified name exists; otherwise, false.
+ public bool ContainsProperty(string name)
+ {
+ return Properties.ContainsKey(name);
+ }
+
///
/// Returns the enumeration of all dynamic member names.
///
diff --git a/src/System.Linq.Dynamic.Core/DynamicClass.uap.cs b/src/System.Linq.Dynamic.Core/DynamicClass.uap.cs
index 8778de98..cf28afd3 100644
--- a/src/System.Linq.Dynamic.Core/DynamicClass.uap.cs
+++ b/src/System.Linq.Dynamic.Core/DynamicClass.uap.cs
@@ -12,7 +12,7 @@ public class DynamicClass : DynamicObject
{
internal const string IndexerName = "System_Linq_Dynamic_Core_DynamicClass_Indexer";
- private readonly Dictionary _properties = new();
+ private readonly Dictionary _properties = new();
///
/// Initializes a new instance of the class.
@@ -35,7 +35,7 @@ public DynamicClass(params KeyValuePair[] propertylist)
/// The name.
/// Value from the property.
[IndexerName(IndexerName)]
- public object this[string name]
+ public object? this[string name]
{
get
{
@@ -59,6 +59,16 @@ public object this[string name]
}
}
+ ///
+ /// Determines whether a property with the specified name exists in the collection.
+ ///
+ /// The name of the property to locate. Cannot be null.
+ /// true if a property with the specified name exists; otherwise, false.
+ public bool ContainsProperty(string name)
+ {
+ return _properties.ContainsKey(name);
+ }
+
///
/// Returns the enumeration of all dynamic member names.
///
diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
index fefd5b66..8222d4d7 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionHelper.cs
@@ -11,6 +11,7 @@ namespace System.Linq.Dynamic.Core.Parser;
internal class ExpressionHelper : IExpressionHelper
{
+ private static readonly Expression _nullExpression = Expression.Constant(null);
private readonly IConstantExpressionWrapper _constantExpressionWrapper = new ConstantExpressionWrapper();
private readonly ParsingConfig _parsingConfig;
@@ -340,7 +341,7 @@ public bool TryGenerateAndAlsoNotNullExpression(Expression sourceExpression, boo
// Convert all expressions into '!= null' expressions (only if the type can be null)
var binaryExpressions = expressions
.Where(expression => TypeHelper.TypeCanBeNull(expression.Type))
- .Select(expression => Expression.NotEqual(expression, Expression.Constant(null)))
+ .Select(expression => Expression.NotEqual(expression, _nullExpression))
.ToArray();
// Convert all binary expressions into `AndAlso(...)`
@@ -393,16 +394,46 @@ public bool TryConvertTypes(ref Expression left, ref Expression right)
if (left.Type == typeof(object))
{
+ if (TryGetAsIndexerExpression(left, out var ce))
+ {
+ var rightTypeAsNullableType = TypeHelper.GetNullableType(right.Type);
+
+ right = Expression.Convert(right, rightTypeAsNullableType);
+
+ left = Expression.Condition(
+ ce.Test,
+ Expression.Convert(ce.IfTrue, rightTypeAsNullableType),
+ Expression.Convert(_nullExpression, rightTypeAsNullableType)
+ );
+
+ return true;
+ }
+
left = Expression.Condition(
- Expression.Equal(left, Expression.Constant(null, typeof(object))),
+ Expression.Equal(left, _nullExpression),
GenerateDefaultExpression(right.Type),
Expression.Convert(left, right.Type)
);
}
else if (right.Type == typeof(object))
{
+ if (TryGetAsIndexerExpression(right, out var ce))
+ {
+ var leftTypeAsNullableType = TypeHelper.GetNullableType(left.Type);
+
+ left = Expression.Convert(left, leftTypeAsNullableType);
+
+ right = Expression.Condition(
+ ce.Test,
+ Expression.Convert(ce.IfTrue, leftTypeAsNullableType),
+ Expression.Convert(_nullExpression, leftTypeAsNullableType)
+ );
+
+ return true;
+ }
+
right = Expression.Condition(
- Expression.Equal(right, Expression.Constant(null, typeof(object))),
+ Expression.Equal(right, _nullExpression),
GenerateDefaultExpression(left.Type),
Expression.Convert(right, left.Type)
);
@@ -546,4 +577,17 @@ private static object[] ConvertIfIEnumerableHasValues(IEnumerable? input)
return [];
}
+
+ private static bool TryGetAsIndexerExpression(Expression expression, [NotNullWhen(true)] out ConditionalExpression? indexerExpresion)
+ {
+ indexerExpresion = expression as ConditionalExpression;
+ if (indexerExpresion == null)
+ {
+ return false;
+ }
+
+ return
+ indexerExpresion.IfTrue.ToString().Contains(DynamicClass.IndexerName) &&
+ indexerExpresion.Test.ToString().Contains("ContainsProperty");
+ }
}
\ No newline at end of file
diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
index b0fb8157..b8091f55 100644
--- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
@@ -1921,11 +1921,35 @@ private Expression ParseMemberAccess(Type? type, Expression? expression, string?
if (!_parsingConfig.DisableMemberAccessToIndexAccessorFallback && extraCheck)
{
- var indexerName = TypeHelper.IsDynamicClass(type!) ? DynamicClass.IndexerName : "Item";
+ var isDynamicClass = TypeHelper.IsDynamicClass(type!);
+ var indexerName = isDynamicClass ? DynamicClass.IndexerName : "Item";
+
+ // Try to get the indexer property "Item" or "DynamicClass_Indexer" which takes a string as parameter
var indexerMethod = expression?.Type.GetMethod($"get_{indexerName}", [typeof(string)]);
if (indexerMethod != null)
{
- return Expression.Call(expression, indexerMethod, Expression.Constant(id));
+ if (!isDynamicClass)
+ {
+ return Expression.Call(expression, indexerMethod, Expression.Constant(id));
+ }
+
+ var containsPropertyMethod = typeof(DynamicClass).GetMethod("ContainsProperty");
+ if (containsPropertyMethod == null)
+ {
+ return Expression.Call(expression, indexerMethod, Expression.Constant(id));
+ }
+
+ var callContainsPropertyExpression = Expression.Call(
+ expression!,
+ containsPropertyMethod,
+ Expression.Constant(id)
+ );
+
+ return Expression.Condition(
+ Expression.Equal(callContainsPropertyExpression, Expression.Constant(true)),
+ Expression.Call(expression, indexerMethod, Expression.Constant(id)),
+ Expression.Constant(null)
+ );
}
}
diff --git a/src/System.Linq.Dynamic.Core/Parser/NumberParser.cs b/src/System.Linq.Dynamic.Core/Parser/NumberParser.cs
index 798ff097..f4bbc731 100644
--- a/src/System.Linq.Dynamic.Core/Parser/NumberParser.cs
+++ b/src/System.Linq.Dynamic.Core/Parser/NumberParser.cs
@@ -149,7 +149,7 @@ public Expression ParseIntegerLiteral(int tokenPosition, string text)
throw new ParseException(Res.MinusCannotBeAppliedToUnsignedInteger, tokenPosition);
}
- if (value <= int.MaxValue)
+ if (value >= int.MinValue && value <= int.MaxValue)
{
return _constantExpressionHelper.CreateLiteral((int)value, textOriginal);
}
diff --git a/test/System.Linq.Dynamic.Core.NewtonsoftJson.Tests/NewtonsoftJsonTests.cs b/test/System.Linq.Dynamic.Core.NewtonsoftJson.Tests/NewtonsoftJsonTests.cs
index e391ed29..759f156f 100644
--- a/test/System.Linq.Dynamic.Core.NewtonsoftJson.Tests/NewtonsoftJsonTests.cs
+++ b/test/System.Linq.Dynamic.Core.NewtonsoftJson.Tests/NewtonsoftJsonTests.cs
@@ -1,5 +1,4 @@
-using System.Linq.Dynamic.Core.Exceptions;
-using System.Linq.Dynamic.Core.NewtonsoftJson.Config;
+using System.Linq.Dynamic.Core.NewtonsoftJson.Config;
using FluentAssertions;
using Newtonsoft.Json.Linq;
using Xunit;
@@ -13,11 +12,13 @@ public class NewtonsoftJsonTests
[
{
"Name": "John",
- "Age": 30
+ "Age": 30,
+ "IsNull": null
},
{
"Name": "Doe",
- "Age": 40
+ "Age": 40,
+ "AlsoNull": null
}
]
""";
@@ -516,12 +517,14 @@ public void Where_With_Select()
[InlineData("notExisting == \"1\"")]
[InlineData("notExisting == \"something\"")]
[InlineData("notExisting > 1")]
+ [InlineData("notExisting < 1")]
[InlineData("true == notExisting")]
[InlineData("\"true\" == notExisting")]
[InlineData("1 == notExisting")]
[InlineData("\"1\" == notExisting")]
[InlineData("\"something\" == notExisting")]
[InlineData("1 < notExisting")]
+ [InlineData("1 > notExisting")]
public void Where_NonExistingMember_EmptyResult(string predicate)
{
// Arrange
@@ -567,6 +570,6 @@ public void NormalizeArray_When_NormalizeIsFalse_ShouldThrow()
Action act = () => JArray.Parse(array).Where(config, "Age >= 30");
// Assert
- act.Should().Throw().WithMessage("The binary operator GreaterThanOrEqual is not defined for the types 'System.Object' and 'System.Int32'.");
+ act.Should().Throw().WithMessage("Unable to find property 'Age' on type '<>*");
}
}
\ No newline at end of file
diff --git a/test/System.Linq.Dynamic.Core.SystemTextJson.Tests/SystemTextJsonTests.cs b/test/System.Linq.Dynamic.Core.SystemTextJson.Tests/SystemTextJsonTests.cs
index e699e086..9a81f76a 100644
--- a/test/System.Linq.Dynamic.Core.SystemTextJson.Tests/SystemTextJsonTests.cs
+++ b/test/System.Linq.Dynamic.Core.SystemTextJson.Tests/SystemTextJsonTests.cs
@@ -17,11 +17,13 @@ public class SystemTextJsonTests
[
{
"Name": "John",
- "Age": 30
+ "Age": 30,
+ "IsNull": null
},
{
"Name": "Doe",
- "Age": 40
+ "Age": 40,
+ "AlsoNull": null
}
]
""";
@@ -161,20 +163,20 @@ public void Distinct()
public void First()
{
// Act + Assert 1
- _source.First().GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""John"",""Age"":30}").RootElement.GetRawText());
+ _source.First().GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""John"",""Age"":30,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 2
- _source.First("Age > 30").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.First("Age > 30").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
}
[Fact]
public void FirstOrDefault()
{
// Act + Assert 1
- _source.FirstOrDefault()!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""John"",""Age"":30}").RootElement.GetRawText());
+ _source.FirstOrDefault()!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""John"",""Age"":30,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 2
- _source.FirstOrDefault("Age > 30")!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.FirstOrDefault("Age > 30")!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 3
_source.FirstOrDefault("Age > 999").Should().BeNull();
@@ -267,20 +269,20 @@ public void GroupBySimpleKeySelector()
public void Last()
{
// Act + Assert 1
- _source.Last().GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.Last().GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 2
- _source.Last("Age > 0").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.Last("Age > 0").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
}
[Fact]
public void LastOrDefault()
{
// Act + Assert 1
- _source.LastOrDefault()!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.LastOrDefault()!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 2
- _source.LastOrDefault("Age > 0")!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.LastOrDefault("Age > 0")!.Value.GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
// Act + Assert 3
_source.LastOrDefault("Age > 999").Should().BeNull();
@@ -444,7 +446,7 @@ public void SelectMany()
public void Single()
{
// Act + Assert
- _source.Single("Age > 30").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40}").RootElement.GetRawText());
+ _source.Single("Age > 30").GetRawText().Should().BeEquivalentTo(JsonDocument.Parse(@"{""Name"":""Doe"",""Age"":40,""IsNull"":null,""AlsoNull"":null}").RootElement.GetRawText());
}
[Fact]
@@ -544,12 +546,14 @@ public void Where_With_Select()
[InlineData("notExisting == \"1\"")]
[InlineData("notExisting == \"something\"")]
[InlineData("notExisting > 1")]
+ [InlineData("notExisting < 1")]
[InlineData("true == notExisting")]
[InlineData("\"true\" == notExisting")]
[InlineData("1 == notExisting")]
[InlineData("\"1\" == notExisting")]
[InlineData("\"something\" == notExisting")]
[InlineData("1 < notExisting")]
+ [InlineData("1 > notExisting")]
public void Where_NonExistingMember_EmptyResult(string predicate)
{
// Act
diff --git a/test/System.Linq.Dynamic.Core.Tests/Parser/NumberParserTests.cs b/test/System.Linq.Dynamic.Core.Tests/Parser/NumberParserTests.cs
index f8ccc496..2f8a8ed8 100644
--- a/test/System.Linq.Dynamic.Core.Tests/Parser/NumberParserTests.cs
+++ b/test/System.Linq.Dynamic.Core.Tests/Parser/NumberParserTests.cs
@@ -1,8 +1,8 @@
-using FluentAssertions;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Dynamic.Core.Parser;
using System.Linq.Expressions;
+using FluentAssertions;
using Xunit;
namespace System.Linq.Dynamic.Core.Tests.Parser;
@@ -129,6 +129,8 @@ public void NumberParser_ParseNumber_Double(string? culture, string text, double
[Theory]
[InlineData("42", 42)]
[InlineData("-42", -42)]
+ [InlineData("3000000000", 3000000000)]
+ [InlineData("-3000000000", -3000000000)]
[InlineData("77u", 77)]
[InlineData("77l", 77)]
[InlineData("77ul", 77)]
diff --git a/version.xml b/version.xml
index c8f45c09..d0d14392 100644
--- a/version.xml
+++ b/version.xml
@@ -1,5 +1,5 @@
- 0
+ 1
\ No newline at end of file