-
-
Notifications
You must be signed in to change notification settings - Fork 266
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 multiple types of parameter resolution #419
Conversation
Moved into PR description for clarity |
looks like something went wrong
what do I need to do? |
Please:
Thank you! |
I don't understand what you mean, can you say something specific? |
if ($value instanceof VariableNode) { | ||
$variableName = $value->name->value; | ||
|
||
return $this->info->variableValues[$variableName] ?? null; | ||
} | ||
// Scalar Types | ||
if ($value instanceof IntValueNode || $value instanceof FloatValueNode || $value instanceof StringValueNode || $value instanceof BooleanValueNode || $value instanceof EnumValueNode) { |
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 think this could be shorten to:
if ($value instanceof ValueNode)
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.
Valuenode contains the following types
/**
export type ValueNode = VariableNode
| NullValueNode
| IntValueNode
| FloatValueNode
| StringValueNode
| BooleanValueNode
| EnumValueNode
| ListValueNode
| ObjectValueNode
*/
The parameter is ListValueNode or ObjectValueNode is not applicable.
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.
@sowork @crissi should we change the order of conditions?
- check for ListValueNode and ObjectVakueNode
- Check for ValueNode
This way we would not be concerned anymore about all the details as they effectively work the same.
Another approach for 2.: we effectively treat the "fallthrough" in this method as always being ValueNode
and return $argumentNode->value
as it currently is?
Would that make sense?
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.
Theoretically feasible, but there is also a nullValueNode
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.
not sure
but checking for the ListValueNode and ObjectVakueNode and nullValueNode first
and then fallthough to just get the value might work. So custom scalar types is also considered, not sure the current implementation take this in account.
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.
but there is also a nullValueNode
Right! Forgot to list it, but that would apply for it too.
So custom scalar types
Oh, interesting. Didn't think about it and currently don't know what kind of node it exactly is.
We need a test for this too. 😄
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.
custom scalar types
for custom scalar types will still be converted to a ValueNode
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 for for, now just waiting for the test(s) :-)
I added a unit test and it should be fine now. |
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.
Many thanks for the PR, I did my first in-depth review today.
I'm in favour of this change and looking forward to include it 👍 but have some feedback regarding style and clarity as well as the tests 🔍
My issue with the test:
- it's slapped on top of an existing but absolutely unrelated test
- all types supported in
\Rebing\GraphQL\Support\ResolveInfoFieldsAndArguments::getValue
should be tested for (currently it misses at least the null type and the variable node; the latter was already there but I think it's the right time to add this) - there are no real assertions on the new code: rather it implicitly observes the output of the GraphQL result. That's great and useful for many applications, but I think in this particular one it should be more explicit
My suggestion is:
- it should be a standalone test, i.e. create a new directory/namespace in
tests/Database/SelectFields
- the (new)
FilterInput
should cover all types supported ingetValue
- the assertions should be done when the
'query'
receives the arguments, i.e. with the types the full$args
could be compared to a expected array using\PHPUnit\Framework\Assert::assertSame
=> see\Rebing\GraphQL\Tests\Database\SelectFields\ValidateFieldTests\PostType::fields
for an example. Having to add fixtures / results for a test just bloats for not obvious reasons. A assertion directly where we receive the data ASAP we transformed it seems most appropriate for me.- As such I would suggest to remove all the newly added models, types, etc. and only concentrate on the essential as outlined above
What do you think?
return $this->getInputListObjectValue($value); | ||
} | ||
|
||
throw new \Exception('Failed to resolve unknown ValueNode type'); |
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.
If you don't add a specific exception, please use at least RuntimeException
(and import it)
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.
How can this be triggered with the current code?
Would like to see a test for this.
@@ -76,6 +85,7 @@ public function __construct(ResolveInfo $info) | |||
* @param int $depth How many levels to include in output | |||
* @return array | |||
* @see \GraphQL\Type\Definition\ResolveInfo::getFieldSelection | |||
* @throws \Exception |
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.
Please remove all the @throws
you added in this PR
They are deliberately not added because it's a PITA to maintain them. Code changes, exception changes and before you notice it, it's out of date.
if ($value instanceof IntValueNode || $value instanceof FloatValueNode || $value instanceof StringValueNode || $value instanceof BooleanValueNode || $value instanceof EnumValueNode) { | ||
return $value->value; | ||
} | ||
// null Type |
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 think the code speaks for itself, remove the comment (but leave a blank line)
if ($value instanceof NullValueNode) { | ||
return; | ||
} | ||
// object Type |
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 think the code speaks for itself, remove the comment (but leave a blank line)
if ($value instanceof ObjectValueNode) { | ||
return $this->getInputObjectValue($value); | ||
} | ||
// list object Type |
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 think the code speaks for itself, remove the comment (but leave a blank line)
* @return array | ||
* @throws \Exception | ||
*/ | ||
private function getInputListObjectValue(ListValueNode $listValueNode) |
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.
add return type decl :array
} | ||
// null Type | ||
if ($value instanceof NullValueNode) { | ||
return; |
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.
Shouldn't this be more explicit and actually return 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.
Originally I returned null, but styleci
changed to this way by 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.
How strange, thanks!
{ | ||
$value = []; | ||
foreach ($objectValueNode->fields->getIterator() as $item) { | ||
if ($item instanceof ObjectFieldNode) { |
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.
Not sure about this.
The code makes it look like $item
could be something else. But reading \GraphQL\Language\AST\ObjectValueNode::$fields
it's clear this is not intended.
How can we improve this? Should we remove the check? Or add an } else {
and throw an exception?
Because as it is right now, if that case ever would happen, we silently would carry on.
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.
- Currently, item only handles objects of type ObjectFieldNode
- If the current item object contains other scalar types or listNode and so on, the resolution continues recursively
@@ -42,8 +42,6 @@ parameters: | |||
- '/Cannot call method set\(\) on Illuminate\\Config\\Repository\|null/' | |||
- '/Parameter #4 \$currentPage of class Illuminate\\Pagination\\LengthAwarePaginator constructor expects int\|null, float\|int given/' | |||
- '/Parameter #1 \$offset of method Illuminate\\Support\\Collection::slice\(\) expects int, float\|int given/' | |||
# \Rebing\GraphQL\Support\ResolveInfoFieldsAndArguments::getValue | |||
- '/Access to an undefined property GraphQL\\Language\\AST\\ValueNode::\$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.
This pretty cool and a very clear indicator that the current code was broken :/ Great 👍
if ($value instanceof VariableNode) { | ||
$variableName = $value->name->value; | ||
|
||
return $this->info->variableValues[$variableName] ?? null; | ||
} | ||
// Scalar Types | ||
if ($value instanceof IntValueNode || $value instanceof FloatValueNode || $value instanceof StringValueNode || $value instanceof BooleanValueNode || $value instanceof EnumValueNode) { |
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.
Please break the lines: there are so many ORs, they really need to be better readable.
For simplicity, I suggest each one gets its own line:
if ($value instanceof IntValueNode ||
$value instanceof FloatValueNode ||
…
Apply fixes from StyleCI
Apply fixes from StyleCI
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, looking very good 👍
} | ||
// null Type | ||
if ($value instanceof NullValueNode) { | ||
return; |
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.
How strange, thanks!
* @param ValueNode $value | ||
* @return mixed | ||
* @throws \Exception | ||
*/ |
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.
Removed it
* @param ObjectValueNode $objectValueNode | ||
* @return array | ||
* @throws \Exception | ||
*/ |
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.
Removed it
* @param ListValueNode $listValueNode | ||
* @return array | ||
* @throws \Exception | ||
*/ |
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.
Removed it
use SqlAssertionTrait; | ||
|
||
/** | ||
* Fixed with https://github.com/rebing/graphql-laravel/pull/419. |
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 removed this reference; it would only have made sense for code which existing prior to this PR.
$args is parsed incorrectly when the parameter passed in is an object or listObject