Skip to content
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

Compare JSON literals in Strict mode #2464

Merged
merged 13 commits into from
Sep 18, 2021

Conversation

Kantis
Copy link
Member

@Kantis Kantis commented Sep 6, 2021

Aim is to fix #2458

It got a bit more complicated than simply checking exact equal string representations in Strict mode. Given that 1.0E2 is the same number as 100.0, 100 or +1E+2 I think they should be considered equal. What do you think?

The JSON standard seems to not make any distinction between integer and floating point numbers.

TODO:

  • Changelog?
  • Update relevant docs

Side-note: Do you have a good way of writing tests that targets both JVM and JS platforms? I didn't like copying the JsonLiteralTest class to both targets. I tried adding a test factory to commonTest and including that from both platforms, but then it was hard to run a specific test within the spec.

@Kantis Kantis marked this pull request as ready for review September 7, 2021 17:49
Copy link
Member

@jschneidereit jschneidereit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome work!

@sksamuel
Copy link
Member

sksamuel commented Sep 10, 2021

I think if you activate strict mode, then "100.0" does not equal "1.0E2".
Because if we consider those equal, where do we draw the line? Is 00001 the same as 1 ?
Unless the json spec says that numbers in strings should be treated as special numbers, then I think we just consider them strings.
In lenient mode, I think we can do cleverer things.

@sksamuel
Copy link
Member

Let me know when this is ready again for a review.

@Kantis
Copy link
Member Author

Kantis commented Sep 10, 2021

I think if you activate strict mode, then "100.0" does not equal "1.0E2".
Because if we consider those equal, where do we draw the line? Is 00001 the same as 1 ?
Unless the json spec says that numbers in strings should be treated as special numbers, then I think we just consider them strings.
In lenient mode, I think we can do cleverer things.

I think we should draw a line between literals (100) and strings ("100").

When working with literals, IMO we should treat every number that is same number but different format (not type) as the same.
(1.0 == 1 != "1" != 01 (invalid number)).

But it's only my opinion 😄 I can revert to exact literal comparison, e.g. value must be identical (100.0 != 1.0E2) if you wish

I added test showing that we don't do type-conversion for quoted numbers in strict mode.

@sksamuel
Copy link
Member

As discussed on chat, I would update compare mode to use this:

enum class CompareMode {

   /**
    * Types and formats must be identical.
    *
    * For example, "true" and true will not match because one is a string, and the other is a boolean.
    * Similarly, 2.99E9 and 299000000 would not match because despite both being doubles, and the same value,
    * they are not using the same representation.
    */
   Exact,

   /**
    * Types must be identical and compare by value.
    *
    * For example, "true" and true will not match because one is a string, and the other is a boolean.
    * But 2.99E9 and 299000000 are considered equal as they are both doubles, and both represent the same number.
    * "100" and 100 would not match as they are different types.
    */
   Strict,

   /**
    * Compare by value, coercing if possible.
    *
    * For example, "true" and true will match because the string value can be coerced into a valid boolean.
    * Similarly, "100" and 100 will match as the former can be coerced into an int.
    */
   Lenient,
}

@sksamuel
Copy link
Member

sksamuel commented Sep 11, 2021 via email

@sksamuel
Copy link
Member

Let me know when you want a re-review.

@Kantis
Copy link
Member Author

Kantis commented Sep 16, 2021

@sksamuel I think this is ready for final review. I haven't come up with any better names for CompareMode.Exact ☹️

@sksamuel sksamuel merged commit da45219 into kotest:master Sep 18, 2021
@sksamuel
Copy link
Member

Nice job :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

shouldEqualJson in Strict mode should compare raw values
3 participants