-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Additional tests for System.Text.Json #32705
Conversation
Hi thanks for the contribution! Btw we don't really use "draft" PRs here. Is this ready for review? |
@danmosemsft Thanks for letting me know, I've marked it as ready for review. |
I added some additional changes. I'll leave this PR alone from here, and continue working on additional coverage improvements in another PR. Note 1runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs Lines 291 to 293 in fd181c0
In the previous line, we cast the current instance to a However, to make sure this is safely enforced, I thought it would be good to explicitly mark Note 2Lines 68 to 71 in fd181c0
I'm fairly confident this is unreachable. There are two calling methods:
Note 3Lines 21 to 24 in 59dde05
That call chain throws a NRE if Lines 30 to 39 in 59dde05
|
@@ -21,6 +21,9 @@ public static partial class JsonSerializer | |||
/// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the write operation.</param> | |||
public static Task SerializeAsync<TValue>(Stream utf8Json, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) | |||
{ | |||
if (utf8Json == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. We should update the docs with the new exceptions:
https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.serializeasync?view=netcore-3.1#System_Text_Json_JsonSerializer_SerializeAsync_System_IO_Stream_System_Object_System_Type_System_Text_Json_JsonSerializerOptions_System_Threading_CancellationToken_
If you get the chance, please add the exceptions this (and other SerializeAsync overloads) throw, here (if you are up for it, this would need a PR in the docs repo):
https://github.com/dotnet/dotnet-api-docs/blob/1e6b2e6052185c6744054acc10cd06e435a4fb8b/xml/System.Text.Json/JsonSerializer.xml#L546-L563
See other overloads that have exception docs as an example:
https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.serialize?view=netcore-3.1#System_Text_Json_JsonSerializer_Serialize__1_System_Text_Json_Utf8JsonWriter___0_System_Text_Json_JsonSerializerOptions_
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do, thanks for the pointers to the docs code and example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created issue dotnet/dotnet-api-docs#3961
{ | ||
await Assert.ThrowsAsync<ArgumentNullException>(async () => await JsonSerializer.DeserializeAsync<string>((Stream)null)); | ||
await Assert.ThrowsAsync<ArgumentNullException>(async () => await JsonSerializer.DeserializeAsync((Stream)null, (Type)null)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we are doing this, let's add all permutations. For example: have the stream parameter be null, but the type parameter be non-null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 7a6e0cb
|
||
ReadOnlySequence<byte> sequence = JsonTestHelper.CreateSegments(dataUtf8); | ||
|
||
var json = new Utf8JsonReader(sequence, isFinalBlock: false, state: default); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Consider looping through the entire sequence and creating slices of arbitrary lengths (and re-entering the reader with "partial data"). See other "single value" tests like: TestSingleStringsMultiSegment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried something out with 823f147, let me know if that doesn't cover what you were thinking.
@@ -290,45 +290,27 @@ internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, Json | |||
bool success; | |||
JsonDictionaryConverter<T> dictionaryConverter = (JsonDictionaryConverter<T>)this; | |||
|
|||
if (ClassType == ClassType.Value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if it is OK to remove this (it's possible that it is OK to do, but is surprising to me). What happens when the user defines and register their own JsonConverter<T>
for dictionaries?
@steveharter, @layomia - please review this when you get a chance. I suspect this branch was needed for something (which means we need to provide the test case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I touched on this in Note 1 in the above comments, but I'm not sure it's possible. The line immediately above this one casts the current instance to a JsonDictionaryConverter<T>
which is marked internal
, so my assumption was users wouldn't be able to inherit it (unless there's something I'm not thinking of or aware of?)
I can certainly leave this in there if that's the call, but I think then testing and getting coverage on these lines would be difficult without introducing an InternalsVisibleTo
relationship (or similar internals-testing-pattern) between the src and test project. That or adding an inherited class in the src project for the purposes of testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bug with writing extension data if there is a custom converter for the extension property: #32903. This is the reason why the L291 is not problematic (InvalidCastException
) - we throw an NRE up stack.
We'll likely need this branch when we fix that bug, so for this PR we should revert this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted in 256de92
@@ -9,7 +9,7 @@ namespace System.Text.Json.Serialization | |||
/// </summary> | |||
internal abstract class JsonDictionaryConverter<T> : JsonResumableConverter<T> | |||
{ | |||
internal override ClassType ClassType => ClassType.Dictionary; | |||
internal sealed override ClassType ClassType => ClassType.Dictionary; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should seal the overrides in JsonCollectionConverter
and JsonObjectConverter
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 02ab96b
@@ -290,45 +290,27 @@ internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, Json | |||
bool success; | |||
JsonDictionaryConverter<T> dictionaryConverter = (JsonDictionaryConverter<T>)this; | |||
|
|||
if (ClassType == ClassType.Value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bug with writing extension data if there is a custom converter for the extension property: #32903. This is the reason why the L291 is not problematic (InvalidCastException
) - we throw an NRE up stack.
We'll likely need this branch when we fix that bug, so for this PR we should revert this change.
…chable code" This reverts commit 1e8e33c.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @alanisaac!
{ | ||
long tokenLength = jsonReader.HasValueSequence ? jsonReader.ValueSequence.Length : jsonReader.ValueSpan.Length; | ||
Assert.Equal(expectedTokenLength, tokenLength); | ||
Assert.Equal(expectedValue, jsonReader.GetDateTime()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We missed the asserts for TryGetDateTime
and TryGetDateTimeOffset
APIs.
Adding additional tests and removed unreachable code in order to improve code coverage for System.Text.Json, as suggested in #32341.