From 1364fa028ac3bbdf0c9f47c4441df5afcdcf9539 Mon Sep 17 00:00:00 2001 From: Fritz Gerneth Date: Fri, 2 Jun 2017 15:28:01 +0200 Subject: [PATCH 1/3] Implement variable defaults --- src/Execution/Request.php | 6 ++++ src/Parser/Ast/ArgumentValue/Variable.php | 35 +++++++++++++++++++++++ src/Parser/Parser.php | 9 +++++- src/Parser/Token.php | 1 + src/Parser/Tokenizer.php | 5 ++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/Execution/Request.php b/src/Execution/Request.php index 5215674c..428ea0ac 100644 --- a/src/Execution/Request.php +++ b/src/Execution/Request.php @@ -66,6 +66,12 @@ public function __construct($data = [], $variables = []) if (array_key_exists('variableReferences', $data)) { foreach ($data['variableReferences'] as $ref) { if (!array_key_exists($ref->getName(), $variables)) { + /** @var Variable $variable */ + $variable = $ref->getVariable(); + if ($variable->hasDefaultValue()) { + $variables[$variable->getName()] = $variable->getDefaultValue()->getValue(); + continue; + } throw new InvalidRequestException(sprintf("Variable %s hasn't been submitted", $ref->getName()), $ref->getLocation()); } } diff --git a/src/Parser/Ast/ArgumentValue/Variable.php b/src/Parser/Ast/ArgumentValue/Variable.php index 334f9f1f..e5d226ae 100644 --- a/src/Parser/Ast/ArgumentValue/Variable.php +++ b/src/Parser/Ast/ArgumentValue/Variable.php @@ -35,6 +35,12 @@ class Variable extends AbstractAst implements ValueInterface /** @var bool */ private $arrayElementNullable = true; + /** @var bool */ + private $hasDefaultValue = false; + + /** @var mixed */ + private $defaultValue = null; + /** * @param string $name * @param string $type @@ -62,6 +68,9 @@ public function __construct($name, $type, $nullable, $isArray, Location $locatio public function getValue() { if (null === $this->value) { + if ($this->hasDefaultValue()) { + return $this->defaultValue; + } throw new \LogicException('Value is not set for variable "' . $this->name . '"'); } @@ -140,6 +149,32 @@ public function setNullable($nullable) $this->nullable = $nullable; } + /** + * @return bool + */ + public function hasDefaultValue() + { + return $this->hasDefaultValue; + } + + /** + * @return mixed + */ + public function getDefaultValue() + { + return $this->defaultValue; + } + + /** + * @param mixed $defaultValue + */ + public function setDefaultValue($defaultValue) + { + $this->hasDefaultValue = true; + + $this->defaultValue = $defaultValue; + } + /** * @return boolean */ diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index 8c53f3c8..39651582 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -147,7 +147,7 @@ protected function parseVariables() $this->eat(Token::TYPE_REQUIRED); } - $this->data['variables'][] = new Variable( + $variable = new Variable( $nameToken->getData(), $type, $required, @@ -155,6 +155,13 @@ protected function parseVariables() new Location($variableToken->getLine(), $variableToken->getColumn()), $arrayElementNullable ); + + if ($this->match(Token::TYPE_EQUAL)) { + $this->eat(Token::TYPE_EQUAL); + $variable->setDefaultValue($this->parseValue()); + } + + $this->data['variables'][] = $variable; } $this->expect(Token::TYPE_RPAREN); diff --git a/src/Parser/Token.php b/src/Parser/Token.php index 7e708d7f..2925cd42 100644 --- a/src/Parser/Token.php +++ b/src/Parser/Token.php @@ -33,6 +33,7 @@ class Token const TYPE_VARIABLE = '$'; const TYPE_POINT = '.'; const TYPE_REQUIRED = '!'; + const TYPE_EQUAL = '='; const TYPE_NULL = 'null'; const TYPE_TRUE = 'true'; diff --git a/src/Parser/Tokenizer.php b/src/Parser/Tokenizer.php index a66a22d0..de903d26 100644 --- a/src/Parser/Tokenizer.php +++ b/src/Parser/Tokenizer.php @@ -117,6 +117,11 @@ protected function scan() return new Token(Token::TYPE_COLON, $this->getLine(), $this->getColumn()); + case Token::TYPE_EQUAL: + ++$this->pos; + + return new Token(Token::TYPE_EQUAL, $this->getLine(), $this->getColumn()); + case Token::TYPE_POINT: if ($this->checkFragment()) { return new Token(Token::TYPE_FRAGMENT_REFERENCE, $this->getLine(), $this->getColumn()); From d0d561bbd8ed2a4f3bf00980d876aa4a7c2eb745 Mon Sep 17 00:00:00 2001 From: Fritz Gerneth Date: Fri, 2 Jun 2017 15:47:55 +0200 Subject: [PATCH 2/3] Simple tests added --- Tests/Parser/VariableTest.php | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Tests/Parser/VariableTest.php b/Tests/Parser/VariableTest.php index 295f8ad2..957b0b7c 100644 --- a/Tests/Parser/VariableTest.php +++ b/Tests/Parser/VariableTest.php @@ -29,6 +29,48 @@ public function testGetNullValueException() $var->getValue(); } + public function testGetValueReturnsDefaultValueIfNoValueSet() + { + $var = new Variable('foo', 'bar', false, false, new Location(1,1)); + $var->setDefaultValue('default-value'); + + $this->assertEquals( + 'default-value', + $var->getValue() + ); + } + + public function testGetValueReturnsSetValueEvenWithDefaultValue() + { + $var = new Variable('foo', 'bar', false, false, new Location(1,1)); + $var->setValue('real-value'); + $var->setDefaultValue('default-value'); + + $this->assertEquals( + 'real-value', + $var->getValue() + ); + } + + public function testIndicatesDefaultValuePresent() + { + $var = new Variable('foo', 'bar', false, false, new Location(1,1)); + $var->setDefaultValue('default-value'); + + $this->assertTrue( + $var->hasDefaultValue() + ); + } + + public function testHasNoDefaultValue() + { + $var = new Variable('foo', 'bar', false, false, new Location(1,1)); + + $this->assertFalse( + $var->hasDefaultValue() + ); + } + /** * @return array Array of */ @@ -41,4 +83,4 @@ public static function variableProvider() ] ]; } -} \ No newline at end of file +} From 5b27235796862e98b182131fff0b3fbccb023c1c Mon Sep 17 00:00:00 2001 From: Alexandr Viniychuk Date: Sat, 3 Jun 2017 14:12:41 -0400 Subject: [PATCH 3/3] test for parser --- Tests/Parser/ParserTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Tests/Parser/ParserTest.php b/Tests/Parser/ParserTest.php index ec76a441..0144676b 100644 --- a/Tests/Parser/ParserTest.php +++ b/Tests/Parser/ParserTest.php @@ -823,4 +823,21 @@ public function testVariablesInQuery() $this->assertArrayNotHasKey('errors', $data); } + public function testVariableDefaultValue() + { + $parser = new Parser(); + $parsedStructure = $parser->parse(' + query ($format: String = "small"){ + user { + avatar(format: $format) + } + } + '); + /** @var Variable $var */ + $var = $parsedStructure['variables'][0]; + $this->assertTrue($var->hasDefaultValue()); + $this->assertEquals('small', $var->getDefaultValue()->getValue()); + $this->assertEquals('small', $var->getValue()->getValue()); + } + }