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
Draft for Json comparison function using Utf8JsonReader #2493
base: develop
Are you sure you want to change the base?
Conversation
Qodana for .NETIt seems all right 👌 No new problems were found according to the checks applied 💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
I like this. I'm just wondering whether this should be part of broader support for |
😁 me too 😀
Maybe?, but the API in this PR does not expose anything related to a specific json library (apart from the comment handling enum). It’s just a new mode for string comparisons along with case sensitive and case insensitive. I thought about extending the assertion to work on general objects, but ended up not liking the idea, because I’d only save the user from explicit serializing, and have issues about what serializer and settings to use. |
True. What do you think about this @jnyrup ? |
What is a proper way forward now? I think this api is a generally useful way of comparing objects that I would like to see available in the core FluentAssertions library to have it available in all projects, (in lines of code it is very small!), but as far as I can tell there is nothing stopping me from creating and maintaining a separate package to refine and get some feedback on the api and port over later. |
I'm waiting for some feedback from @jnyrup. Remember, this is an open-source project that we work on in our private time, which is limited... |
I find the approach interesting because it treats the json as json structures and not C# structures. On the other hand, I fail to see the use cases that aren't covered by
Case insensitive property matching sounds like something that might be useful in the general equivalency engine. |
In his example, comparing to JSON strings would do just that, comparing strings. |
Funny thing. I tried to use this and it caught what I consider a bug. Note that the timezones are different, but the instance is the same. public class Test
{
public DateTime date { get; set; }
}
var myActualString = """{"date": "2020-02-07T10:46:36+01:00"}""";
var expectedString = """{"date": "2020-02-07T09:46:36+00:00"}""";
var myActual = JsonSerializer.Deserialize<Test>(myActualString);
var expected = JsonSerializer.Deserialize<Test>(expectedString);
// This thinks that they are equal
expected.Should().BeEquivalentTo(myActual); // Test OK
// But clients of an API might care that we now serialise with another timezone.
// The strings are not Json equivalent
expectedString.Should().BeJsonEquivalentTo(myActualString); // Throws |
The big difference between |
Actually, this shouldn't throw at all, since both dates are equivalent. |
Depends on the eye looking I suppose. I think this would be nice to be informed about a change in timezone by a failing assertion. Also the JSON specification doesn't define how dates should look, so I don't know how you'd know that a string should be parsed as a date/timestamp. |
Those statements alone are enough to make this discussion even more complicated. I gave both examples to ChatGPT and it confirmed they were functionally equivalent, assuming you treat them as ISO 8601 dates. You're right about the lack of a specification, but people are used to seeing dates and times in that format. In fact, ISO 8601 is the default for the parses in |
System.Text.Json provides a neat api for parsing Json in a forward only way with
Utf8JsonReader
that just returns tokens, ignoring whitespace and decoding escape sequences in strings.This would make a lot of sense in tests that produce json to check that it still matches the expected content, while ignoring whitespace and other artefacts that are ignored by a json deserialiser. Currently the only options are
Should().Be()
andstring.Should().BeEquivalentTo()
.There are previous issues related to Json and the use of
System.Text.Json
in newer dotnet versions. #2205.I just wanted to add my suggestion for how this might be done. I hope it is OK to suggest in PR form, instead of opening an issue to discuss this somewhat different approach.
I have added a new
JsonComparatorOptions
struct extendingSystem.Text.Json.JsonReaderOptions
with more comparison relevant options. It is optional to provide, but I think the api needs a way to specifyCommentHandeling
,AllowTrailingCommas
andMaxDepth
, and I also have some ideas for more of these Mode options for how to compare structures.Future ideas for possible options (currently not implemented)
{"a": 1, "b": 2}
and{"b": 2, "a": 1}
can be considered equal, even though the order is different.IMPORTANT
./build.sh --target spellcheck
or.\build.ps1 --target spellcheck
before pushing and check the good outcome