Skip to content

Commit

Permalink
Merge branch 'funct-variable-default-values'
Browse files Browse the repository at this point in the history
  • Loading branch information
viniychuk committed Jun 3, 2017
2 parents 11b38db + 5b27235 commit 23fbf30
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 2 deletions.
17 changes: 17 additions & 0 deletions Tests/Parser/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

}
44 changes: 43 additions & 1 deletion Tests/Parser/VariableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <mixed: value to set, mixed: expected value>
*/
Expand All @@ -41,4 +83,4 @@ public static function variableProvider()
]
];
}
}
}
6 changes: 6 additions & 0 deletions src/Execution/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/Parser/Ast/ArgumentValue/Variable.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 . '"');
}

Expand Down Expand Up @@ -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
*/
Expand Down
9 changes: 8 additions & 1 deletion src/Parser/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,21 @@ protected function parseVariables()
$this->eat(Token::TYPE_REQUIRED);
}

$this->data['variables'][] = new Variable(
$variable = new Variable(
$nameToken->getData(),
$type,
$required,
$isArray,
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);
Expand Down
1 change: 1 addition & 0 deletions src/Parser/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
5 changes: 5 additions & 0 deletions src/Parser/Tokenizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit 23fbf30

Please sign in to comment.