-
Notifications
You must be signed in to change notification settings - Fork 524
[Internal] Query: Added custom serializer coverage tests to ExpressionToSQL.cs #3722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
544c5db
8c55e48
794b06a
58ef6ab
38eea9e
ab9116a
477324c
eb25eb6
db84dba
be79b0c
78e4c52
f825e1d
ba4e33d
1d068e4
eef9bf6
1bcd44f
cb7d335
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,10 @@ namespace Microsoft.Azure.Cosmos.Linq | |
| { | ||
| using System; | ||
| using System.Globalization; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Linq.Expressions; | ||
| using global::Azure.Core.Serialization; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
| using Newtonsoft.Json; | ||
| using Newtonsoft.Json.Converters; | ||
|
|
@@ -30,6 +33,104 @@ public void DateTimeKindIsPreservedTest() | |
| Assert.AreEqual("(a[\"StartDate\"] <= \"2022-05-26\")", sql); | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void EnumIsPreservedAsINTest() | ||
| { | ||
| // Arrange | ||
| CosmosLinqSerializerOptions options = new() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is needed if the code that was removed in #3749 is re-introduced |
||
| { | ||
| //CustomCosmosSerializer = new TestCustomJsonSerializer() | ||
| }; | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Act | ||
| TestEnum[] values = new[] { TestEnum.One, TestEnum.Two }; | ||
| Expression<Func<TestEnumDocument, bool>> expr = a => values.Contains(a.Value); | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(expr.Body, options); | ||
|
|
||
| // Assert | ||
| // Assert.AreEqual("(a[\"Value\"] IN (\"One\", \"Two\"))", sql); // <- TODO - Desired Behavior with CustomSerializer | ||
| Assert.AreEqual("(a[\"Value\"] IN (0, 1))", sql); // <- Actual behavior, with ability to set custom serializor reverted | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void EnumIsPreservedAsEQUALSTest() | ||
| { | ||
| // Arrange | ||
| CosmosLinqSerializerOptions options = new() | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| // CustomCosmosSerializer = new TestCustomJsonSerializer() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as before. |
||
| }; | ||
|
|
||
| // Act | ||
| TestEnum statusValue = TestEnum.One; | ||
| Expression<Func<TestEnumDocument, bool>> expr = a => a.Value == statusValue; | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(expr.Body, options); | ||
|
|
||
| // Assert | ||
| // Assert.AreEqual("(a[\"Value\"] = \"One\")", sql); // <- THIS is the correct value, if we are able to use the custom serializer | ||
| Assert.AreEqual("(a[\"Value\"] = 0)", sql); // <- THIS is the current mis-behavior of the SDK | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void EnumIsPreservedAsEXPRESSIONTest() | ||
| { | ||
| // Arrange | ||
| CosmosLinqSerializerOptions options = new() | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| // CustomCosmosSerializer = new TestCustomJsonSerializer() | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| // Act | ||
|
|
||
| // Get status constant | ||
| ConstantExpression status = Expression.Constant(TestEnum.One); | ||
|
|
||
| // Get member access expression | ||
| ParameterExpression arg = Expression.Parameter(typeof(TestEnumNewtonsoftDocument), "a"); | ||
|
|
||
| // Access the value property | ||
| MemberExpression docValueExpression = Expression.MakeMemberAccess( | ||
| arg, | ||
| typeof(TestEnumNewtonsoftDocument).GetProperty(nameof(TestEnumNewtonsoftDocument.Value))! | ||
| ); | ||
|
|
||
| // Create comparison expression | ||
| BinaryExpression expression = Expression.Equal( | ||
| docValueExpression, | ||
| status | ||
| ); | ||
|
|
||
| // Create lambda expression | ||
| Expression<Func<TestEnumNewtonsoftDocument, bool>> lambda = | ||
| Expression.Lambda<Func<TestEnumNewtonsoftDocument, bool>>(expression, arg); | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(lambda.Body, options); | ||
|
|
||
| // Assert | ||
| Assert.AreEqual("(a[\"Value\"] = \"One\")", sql); | ||
| } | ||
|
|
||
| enum TestEnum | ||
| { | ||
| One, | ||
| Two, | ||
| Three, | ||
| } | ||
|
|
||
| class TestEnumDocument | ||
| { | ||
| [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))] // TODO: Remove this once we have the ability to use custom serializer for LINQ queries | ||
| public TestEnum Value { get; set; } | ||
| } | ||
|
|
||
| class TestEnumNewtonsoftDocument | ||
| { | ||
| [JsonConverter(typeof(StringEnumConverter))] | ||
| public TestEnum Value { get; set; } | ||
| } | ||
|
|
||
| class TestDocument | ||
| { | ||
| [JsonConverter(typeof(DateJsonConverter))] | ||
|
|
@@ -50,5 +151,54 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s | |
| } | ||
| } | ||
| } | ||
|
|
||
| /// <remarks> | ||
| // See: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/SystemTextJson/CosmosSystemTextJsonSerializer.cs | ||
| /// </remarks> | ||
| class TestCustomJsonSerializer : CosmosSerializer | ||
| { | ||
| private readonly JsonObjectSerializer systemTextJsonSerializer; | ||
|
|
||
| public static readonly System.Text.Json.JsonSerializerOptions JsonOptions = new() | ||
| { | ||
| DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, | ||
| PropertyNameCaseInsensitive = true, | ||
| Converters = { | ||
| new System.Text.Json.Serialization.JsonStringEnumConverter(), | ||
| } | ||
| }; | ||
|
|
||
| public TestCustomJsonSerializer() | ||
| { | ||
| this.systemTextJsonSerializer = new JsonObjectSerializer(JsonOptions); | ||
| } | ||
|
|
||
| public override T FromStream<T>(Stream stream) | ||
| { | ||
| using (stream) | ||
| { | ||
| if (stream.CanSeek && stream.Length == 0) | ||
| { | ||
| return default; | ||
| } | ||
|
|
||
| if (typeof(Stream).IsAssignableFrom(typeof(T))) | ||
| { | ||
| return (T)(object)stream; | ||
| } | ||
|
|
||
| return (T)this.systemTextJsonSerializer.Deserialize(stream, typeof(T), default); | ||
| } | ||
| } | ||
|
|
||
| public override Stream ToStream<T>(T input) | ||
| { | ||
| MemoryStream stream = new (); | ||
|
|
||
| this.systemTextJsonSerializer.Serialize(stream, input, typeof(T), default); | ||
| stream.Position = 0; | ||
| return stream; | ||
| } | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.