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

Add support for "const" #507

Merged
merged 7 commits into from
May 23, 2018

Conversation

martin-helmich
Copy link
Contributor

As discussed in #506, this PR adds support for the const keyword as first specified in section 6.24 of draft 06.

Fixes #506

'{
"type":"object",
"properties":{
"value":{"type":"string","const":"bar"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm a little curious about the potential use cases covered by this implementation. Ten minutes ago I had never heard of the const keyword, but from what I've read since then its main utility comes from interacting with the $data concept proposed in v5. Given that we don't currently support $data or relative JSON pointers, how much use is there in supporting a keyword that guarantees that an input value is precisely equal to some other value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did not find any mention of the $data concept in the recent spec v7. From my understanding, const is presumably nothing more than a more expressive alternative to a one-element enum:

6.1.3. const
The value of this keyword MAY be of any type, including null.

An instance validates successfully against this keyword if its value is equal to the value of the keyword.

My use case for const is when using a "constant" property as a type discriminator when using polymorphic types:

{
  "$oneOf": [
    {
      "properties": {
        "paymentType": {"type": "string", "const": "directDebit"},
        "iban": {"type": ...}
       }
    },
    {
      "properties": {
        "paymentType": {"type: "string", "const": "creditCard"},
        "cardNumber": {...}
      }
  ]
}

In this case, documents like {"payment": {"paymentType": "directDebit", "iban": "DE1234567890"}} and {"payment": {"paymentType": "creditCard", "cardNumber": "123456789"}} would match the schema, while something like {"payment": {"paymentType": "creditCard", "iban": "DE1234567890"}} would not.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. Okay. 👍

@shmax
Copy link
Collaborator

shmax commented Apr 17, 2018

Does this play nicely with coercion? It would be great if you could add a section somewhere that does a few checks (possibly in CoerciveTests.php...)

@martin-helmich
Copy link
Contributor Author

@shmax Done; I've added a few test cases on how I think const should work with coercion enabled; they all passed without any further changes.

Btw, I noticed that the $tests = [] assignment (formerly line 133) in the CoerciveTests.php caused test cases 39-45 to never be executed; I've re-enabled them, as they were all passing.

'integer', 'string', "42", true
);

// #46 check coercion with "const"
Copy link
Collaborator

Choose a reason for hiding this comment

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

// #47

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@shmax
Copy link
Collaborator

shmax commented Apr 17, 2018

Btw, I noticed that the $tests = [] assignment (formerly line 133) in the CoerciveTests.php caused test cases 39-45 to never be executed;

Egad, it's been that way for a year! Nice catch, thanks much.

Not to be a pest, but can you add one more coercive test to check boolean type? Just to be sure--php is fine with == checks on string/numbers, but not string/boolean.

@martin-helmich
Copy link
Contributor Author

Not to be a pest, but can you add one more coercive test to check boolean type? Just to be sure--php is fine with == checks on string/numbers, but not string/boolean.

👍 Done

);

// #50 check boolean coercion with "const"
$tests[] = array(
Copy link
Collaborator

@shmax shmax Apr 17, 2018

Choose a reason for hiding this comment

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

I was hoping to see a false...

("true" == true) // true
("false" == true) // true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here you go...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Beautiful, thank you


if ($type === gettype($const)) {
if ($type == 'object') {
if ($element == $const) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not correctly implement deep comparison of objects - it results in members being compared using ==.

Could you please change this implementation to ensure type-strict comparison of object properties. You will probably need to iterate them; PHP lacks a suitable native comparison operator that can do it all in one go.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Following that argumentation, the enum implementation (which was my inspiration for this class) should probably be changed as well -- it uses the same comparison.

Copy link
Contributor

Choose a reason for hiding this comment

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

If enum is similarly broken, then yes - I agree with you that it needs fixing.

'{"properties":{"propertyOne":{"type":"boolean","const":true}}}',
'{"propertyOne":1}',
'integer', 'boolean', true, true
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please also add some deep object tests. With and without mismatched property types.

Copy link
Collaborator

@shmax shmax left a comment

Choose a reason for hiding this comment

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

Code LGTM. Will defer to @erayd and @bighappyface for version target considerations.

@erayd
Copy link
Contributor

erayd commented Apr 17, 2018

@shmax I reckon 6.0.0 (which this PR is against), and I'll also backport it for 5.3.0.

Copy link
Collaborator

@bighappyface bighappyface left a comment

Choose a reason for hiding this comment

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

+1 for 9db6594
+1 for 6d04026
+1 for 789c97e
+1 for 1b94558
+1 for 8c3ee91
+1 for 853eb09
+1 for 8a9cd12

@bighappyface bighappyface merged commit a4bf903 into jsonrainbow:master May 23, 2018
@erayd
Copy link
Contributor

erayd commented May 23, 2018

@bighappyface I notice that you have merged this, without a fix for the deep object comparison issue I raised above. Are you intending for that to be fixed in a separate PR? @martin-helmich seems to have abandoned this one without making the necessary change.

@Raphy
Copy link

Raphy commented Jun 5, 2020

Is that normal the version 5.2.8 and 5.X.X do not have this feature ?!
Browsing files from these version and I can't find this feature :(

@erayd
Copy link
Contributor

erayd commented Jun 5, 2020

@Raphy That is correct, yes. This is a draft-06 feature, but is currently incomplete, and not backported.

This library officially supports draft-03 and draft-04, but does not yet fully support newer versions of the spec. Draft-06 is largely similar to draft-04, but there are a few differences, and this is one of them.

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.

Support for "const"?
5 participants