cebe / php-openapi

Read and write OpenAPI yaml/json files and make the content accessible in PHP objects.
MIT License
466 stars 87 forks source link

Unit tests are broken in master since PR #132 #142

Closed victorstanciu closed 2 years ago

victorstanciu commented 2 years ago

The failing tests from PR #132 were merged into master, so now all the checks are failing for new PRs:

There was 1 failure:

1) SchemaTest::testNullable
Failed asserting that false is null.

/home/runner/work/php-openapi/php-openapi/tests/spec/SchemaTest.php:66

The issue is caused by this ternary operator in src/spec/Schema.php, which will always evaluate to true (thereby always setting nullable to false, and never actually null):

https://github.com/cebe/php-openapi/blob/336bd8d3ce449413cbb75273c17a00f13a16426c/src/spec/Schema.php#L130

This always evaluates to the true side of the operator because hasProperty() also returns true if an attribute is defined, whether or not it has a value:

https://github.com/cebe/php-openapi/blob/336bd8d3ce449413cbb75273c17a00f13a16426c/src/SpecBaseObject.php#L300-L303

And of course, type is a defined attribute of the Schema object:

https://github.com/cebe/php-openapi/blob/336bd8d3ce449413cbb75273c17a00f13a16426c/src/spec/Schema.php#L92

I see two quick solutions to this problem, but I wanted to discuss them with you guys before I open a PR:

  1. As far as I see, Schema::attributeDefaults() is the only place where the SpecBaseObject::hasProperty() method is called, so a simple fix (which passes all the tests) would be to simplify the method like this:

       protected function hasProperty(string $name): bool
       {
           return isset($this->_properties[$name]);
       }

    Is there a reason why hasProperty() also checks if an attribute is defined? The method kinda feels misnamed.

  2. The ternary conditional in attributeDefaults() could be rewritten to use isset:

        'nullable' => isset($this->type) ? false : null,

    But isset of course calls __isset(), which itself calls attributeDefaults(), so this might cause a recursion error.

Thoughts?

cebe commented 2 years ago
  1. Is there a reason why hasProperty() also checks if an attribute is defined? The method kinda feels misnamed.

yeah, no idea why this method even exists, it is only called in that one place, so I'm going to fix it this way.

cebe commented 2 years ago

actually came up with an even better fix, added a new method and deprecated hasProperty() so this does not break any extension that might use it.