-
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
Merged
Merged
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
544c5db
Ensure enum as string is preserved for custom serializer
onionhammer 8c55e48
Failing test
onionhammer 794b06a
Added failing tests
onionhammer 58ef6ab
Merge branch 'master' into fix-enum-linq-translation
onionhammer 38eea9e
Merge branch 'master' into fix-enum-linq-translation
onionhammer ab9116a
Updated requested names
onionhammer 477324c
Merge branch 'master' into fix-enum-linq-translation
onionhammer eb25eb6
Merge branch 'master' into fix-enum-linq-translation
onionhammer db84dba
Ignore result of test for now
onionhammer be79b0c
Added additional comment on why the test is ignored
onionhammer 78e4c52
Replaced with sample code
onionhammer f825e1d
Merge branch 'master' into fix-enum-linq-translation
onionhammer ba4e33d
Remove ignore attribute from tests, documented misbehavior for future…
onionhammer 1d068e4
Merge branch 'fix-enum-linq-translation' of https://github.com/onionh…
onionhammer eef9bf6
Updated comment
onionhammer 1bcd44f
Merge branch 'master' into fix-enum-linq-translation
onionhammer cb7d335
Merge branch 'master' into fix-enum-linq-translation
leminh98 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,11 @@ namespace Microsoft.Azure.Cosmos.Linq | |
| { | ||
| using System; | ||
| using System.Globalization; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Linq.Expressions; | ||
| using System.Reflection; | ||
| using global::Azure.Core.Serialization; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
| using Newtonsoft.Json; | ||
| using Newtonsoft.Json.Converters; | ||
|
|
@@ -30,6 +34,101 @@ 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 CustomJsonSerializer() | ||
| }; | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Act | ||
| TestEnum[] values = new[] { TestEnum.One, TestEnum.Two }; | ||
| Expression<Func<EnumContainerDocument, bool>> expr = a => values.Contains(a.Value); | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(expr.Body, options); | ||
|
|
||
| // Assert | ||
| Assert.AreEqual("(a[\"Value\"] IN (\"One\", \"Two\"))", sql); | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void EnumIsPreservedAsEQUALSTest() | ||
| { | ||
| // Arrange | ||
| CosmosLinqSerializerOptions options = new() | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| CustomCosmosSerializer = new CustomJsonSerializer() | ||
| }; | ||
|
|
||
| // Act | ||
| TestEnum statusValue = TestEnum.One; | ||
| Expression<Func<EnumContainerDocument, bool>> expr = a => a.Value == statusValue; | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(expr.Body, options); | ||
|
|
||
| // Assert | ||
| Assert.AreEqual("(a[\"Value\"] = \"One\")", sql); | ||
| } | ||
|
|
||
| [TestMethod] | ||
| public void EnumIsPreservedAsEXPRESSIONTest() | ||
| { | ||
| // Arrange | ||
| CosmosLinqSerializerOptions options = new() | ||
leminh98 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| CustomCosmosSerializer = new CustomJsonSerializer() | ||
| }; | ||
|
|
||
| // Act | ||
|
|
||
| // Get status constant | ||
| ConstantExpression status = Expression.Constant(TestEnum.One); | ||
|
|
||
| // Get member access expression | ||
| ParameterExpression arg = Expression.Parameter(typeof(EnumContainerNewtonsoftAttributeDocument), "a"); | ||
|
|
||
| // Access the value property | ||
| MemberExpression docValueExpression = Expression.MakeMemberAccess( | ||
| arg, | ||
| typeof(EnumContainerNewtonsoftAttributeDocument).GetProperty(nameof(EnumContainerNewtonsoftAttributeDocument.Value))! | ||
| ); | ||
|
|
||
| // Create comparison expression | ||
| BinaryExpression expression = Expression.Equal( | ||
| docValueExpression, | ||
| status | ||
| ); | ||
|
|
||
| // Create lambda expression | ||
| Expression<Func<EnumContainerNewtonsoftAttributeDocument, bool>> lambda = | ||
| Expression.Lambda<Func<EnumContainerNewtonsoftAttributeDocument, bool>>(expression, arg); | ||
|
|
||
| string sql = SqlTranslator.TranslateExpression(lambda.Body, options); | ||
|
|
||
| // Assert | ||
| Assert.AreEqual("(a[\"Value\"] = \"One\")", sql); | ||
| } | ||
|
|
||
| enum TestEnum | ||
| { | ||
| One, | ||
| Two, | ||
| Three, | ||
| } | ||
|
|
||
| class EnumContainerDocument | ||
onionhammer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| public TestEnum Value { get; set; } | ||
| } | ||
|
|
||
| class EnumContainerNewtonsoftAttributeDocument | ||
onionhammer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| [JsonConverter(typeof(StringEnumConverter))] | ||
| public TestEnum Value { get; set; } | ||
| } | ||
|
|
||
| class TestDocument | ||
| { | ||
| [JsonConverter(typeof(DateJsonConverter))] | ||
|
|
@@ -50,5 +149,53 @@ 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> | ||
| public class CustomJsonSerializer : CosmosSerializer | ||
onionhammer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
onionhammer marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| 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 CustomJsonSerializer() | ||
| { | ||
| this.systemTextJsonSerializer = new JsonObjectSerializer(JsonOptions); | ||
| } | ||
|
|
||
| public override T FromStream<T>(Stream stream) | ||
| { | ||
| if (stream.CanSeek && stream.Length == 0) | ||
| { | ||
| stream.Dispose(); | ||
adityasa marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return default!; | ||
| } | ||
|
|
||
| if (typeof(Stream).IsAssignableFrom(typeof(T))) | ||
| return (T)(object)stream; | ||
|
|
||
| using (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; | ||
| } | ||
| } | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.