diff --git a/.travis.yml b/.travis.yml index 1e26a4c47..8768ebebb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ matrix: fast_finish: true include: - php: 5.6 - env: COMPOSER_UPDATE_FLAGS=--prefer-lowest SYMFONY_DEPRECATIONS_HELPER=disabled + env: COMPOSER_UPDATE_FLAGS=--prefer-lowest SYMFONY_DEPRECATIONS_HELPER=disabled GRAPHQLPHP_VERSION=^0.11.2 - php: 5.6 - env: SYMFONY_VERSION=3.1.* SYMFONY_DEPRECATIONS_HELPER=disabled + env: SYMFONY_VERSION=3.1.* SYMFONY_DEPRECATIONS_HELPER=disabled GRAPHQLPHP_VERSION=0.12 - php: 7.0 env: SYMFONY_VERSION=3.2.* PHPUNIT_VERSION=^5.7.26 - php: 7.1 diff --git a/Command/GraphQLDumpSchemaCommand.php b/Command/GraphQLDumpSchemaCommand.php index 3372d0e9a..549d51a1f 100644 --- a/Command/GraphQLDumpSchemaCommand.php +++ b/Command/GraphQLDumpSchemaCommand.php @@ -80,7 +80,8 @@ private function createFile(InputInterface $input) switch ($format) { case 'json': $request = [ - 'query' => Introspection::getIntrospectionQuery(false), + // TODO(mcg-web): remove silence deprecation notices after removing webonyx/graphql-php <= 0.11 + 'query' => @Introspection::getIntrospectionQuery(false), 'variables' => [], 'operationName' => null, ]; diff --git a/Config/Parser/GraphQLParser.php b/Config/Parser/GraphQLParser.php index b9f6d2dd9..a77fb57d7 100644 --- a/Config/Parser/GraphQLParser.php +++ b/Config/Parser/GraphQLParser.php @@ -294,6 +294,9 @@ private function astValueNodeToConfig(ValueNode $valueNode) private function cleanAstDescription($description) { + if (property_exists($description, 'value')) { + $description = $description->value; + } $description = trim($description); return empty($description) ? null : $description; diff --git a/Definition/Type/CustomScalarType.php b/Definition/Type/CustomScalarType.php index 5a04fa3f1..6223ba19d 100644 --- a/Definition/Type/CustomScalarType.php +++ b/Definition/Type/CustomScalarType.php @@ -35,7 +35,7 @@ public function parseValue($value) /** * {@inheritdoc} */ - public function parseLiteral(/* GraphQL\Language\AST\ValueNode */ $valueNode) + public function parseLiteral(/* GraphQL\Language\AST\ValueNode */ $valueNode, array $variables = null) { return $this->call('parseLiteral', $valueNode); } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index d0f25b632..88316163a 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -149,9 +149,7 @@ private function servicesSection() ->scalarNode('expression_language') ->defaultValue(self::NAME.'.expression_language.default') ->end() - ->scalarNode('cache_expression_language_parser') - ->defaultValue(self::NAME.'.cache_expression_language_parser.default') - ->end() + ->scalarNode('cache_expression_language_parser')->end() ->end() ->end(); diff --git a/DependencyInjection/OverblogGraphQLExtension.php b/DependencyInjection/OverblogGraphQLExtension.php index f1423ce44..aa8c9ff93 100644 --- a/DependencyInjection/OverblogGraphQLExtension.php +++ b/DependencyInjection/OverblogGraphQLExtension.php @@ -13,7 +13,6 @@ use Overblog\GraphQLBundle\EventListener\DebugListener; use Overblog\GraphQLBundle\EventListener\ErrorHandlerListener; use Overblog\GraphQLBundle\EventListener\ErrorLoggerListener; -use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -21,7 +20,6 @@ use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\ExpressionLanguage\ParserCache\ArrayParserCache; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\Kernel; @@ -33,7 +31,6 @@ public function load(array $configs, ContainerBuilder $container) $config = $this->treatConfigs($configs, $container); $this->setBatchingMethod($config, $container); - $this->setExpressionLanguageDefaultParser($container); $this->setServicesAliases($config, $container); $this->setSchemaBuilderArguments($config, $container); $this->setSchemaArguments($config, $container); @@ -124,14 +121,6 @@ private function setBatchingMethod(array $config, ContainerBuilder $container) $container->setParameter($this->getAlias().'.batching_method', $config['batching_method']); } - private function setExpressionLanguageDefaultParser(ContainerBuilder $container) - { - $class = version_compare(Kernel::VERSION, '3.2.0', '>=') ? ArrayAdapter::class : ArrayParserCache::class; - $definition = new Definition($class); - $definition->setPublic(false); - $container->setDefinition($this->getAlias().'.cache_expression_language_parser.default', $definition); - } - private function setDebugListener(array $config, ContainerBuilder $container) { if ($config['definitions']['show_debug_info']) { diff --git a/Resources/config/services.yml b/Resources/config/services.yml index e8e1d307f..1027a5f9c 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -75,7 +75,7 @@ services: class: Overblog\GraphQLBundle\ExpressionLanguage\ExpressionLanguage public: false arguments: - - '@overblog_graphql.cache_expression_language_parser' + - '@?overblog_graphql.cache_expression_language_parser' overblog_graphql.cache_compiler: class: Overblog\GraphQLBundle\Generator\TypeGenerator diff --git a/Tests/Config/Parser/GraphQLParserTest.php b/Tests/Config/Parser/GraphQLParserTest.php index ab7ee7454..4b97a388e 100644 --- a/Tests/Config/Parser/GraphQLParserTest.php +++ b/Tests/Config/Parser/GraphQLParserTest.php @@ -19,12 +19,15 @@ public function setUp() public function testParse() { - $fileName = __DIR__.'/fixtures/graphql/schema.graphql'; + $fileName = sprintf( + __DIR__.'/fixtures/graphql/schema%s.graphql', + isset($_SERVER['GRAPHQLPHP_VERSION']) && '^0.11.2' === $_SERVER['GRAPHQLPHP_VERSION'] ? '-0.11' : '' + ); $expected = include __DIR__.'/fixtures/graphql/schema.php'; $this->assertContainerAddFileToResources($fileName); $config = GraphQLParser::parse(new \SplFileInfo($fileName), $this->containerBuilder); - $this->assertEquals($expected, $config); + $this->assertEquals($expected, self::cleanConfig($config)); } public function testParseEmptyFile() @@ -65,4 +68,17 @@ private function assertContainerAddFileToResources($fileName) ->method('addResource') ->with($fileName); } + + private static function cleanConfig($config) + { + foreach ($config as $key => &$value) { + if (is_array($value)) { + $value = self::cleanConfig($value); + } + } + + return array_filter($config, function ($item) { + return !is_array($item) || !empty($item); + }); + } } diff --git a/Tests/Config/Parser/fixtures/graphql/schema-0.11.graphql b/Tests/Config/Parser/fixtures/graphql/schema-0.11.graphql new file mode 100644 index 000000000..3fd725f2d --- /dev/null +++ b/Tests/Config/Parser/fixtures/graphql/schema-0.11.graphql @@ -0,0 +1,54 @@ +# Root Query +type Query { + hero( + # Episode list to use to filter + episodes: [Episode!]! = [NEWHOPE, EMPIRE] + ): Character + # search for a droid + droid(id: ID!): Droid +} + +type Starship { + id: ID! + name: String! + length(unit: LengthUnit = METER): Float +} + +enum Episode { + NEWHOPE + EMPIRE + JEDI +} + +interface Character { + id: ID! + name: String! + friends: [Character] + appearsIn: [Episode]! +} + +type Human implements Character { + id: ID! + name: String! + friends: [Character] + appearsIn: [Episode]! + starships: [Starship] + totalCredits: Int +} + +type Droid implements Character { + id: ID! + name: String! + friends: [Character] + appearsIn: [Episode]! + primaryFunction: String +} + +union SearchResult = Human | Droid | Starship + +input ReviewInput { + stars: Int! = 5 + commentary: String = null +} + +scalar Year diff --git a/Tests/Config/Parser/fixtures/graphql/schema.graphql b/Tests/Config/Parser/fixtures/graphql/schema.graphql index 3fd725f2d..bb9b1732d 100644 --- a/Tests/Config/Parser/fixtures/graphql/schema.graphql +++ b/Tests/Config/Parser/fixtures/graphql/schema.graphql @@ -1,10 +1,10 @@ -# Root Query +"""Root Query""" type Query { hero( - # Episode list to use to filter + """Episode list to use to filter""" episodes: [Episode!]! = [NEWHOPE, EMPIRE] ): Character - # search for a droid + """search for a droid""" droid(id: ID!): Droid } diff --git a/Tests/Functional/App/Type/YearScalarType.php b/Tests/Functional/App/Type/YearScalarType.php index e80a6a3f5..6944f258c 100644 --- a/Tests/Functional/App/Type/YearScalarType.php +++ b/Tests/Functional/App/Type/YearScalarType.php @@ -5,7 +5,6 @@ use GraphQL\Error\Error; use GraphQL\Language\AST\StringValueNode; use GraphQL\Type\Definition\ScalarType; -use GraphQL\Utils; class YearScalarType extends ScalarType { @@ -22,17 +21,13 @@ public function serialize($value) */ public function parseValue($value) { - if (!is_string($value)) { - throw new Error(sprintf('Cannot represent following value as a valid year: %s.', Utils::printSafeJson($value))); - } - return (int) str_replace(' AC', '', $value); } /** * {@inheritdoc} */ - public function parseLiteral($valueNode) + public function parseLiteral($valueNode, array $variables = null) { if (!$valueNode instanceof StringValueNode) { throw new Error('Query error: Can only parse strings got: '.$valueNode->kind, [$valueNode]); diff --git a/Tests/Functional/Command/GraphDumpSchemaCommandTest.php b/Tests/Functional/Command/GraphDumpSchemaCommandTest.php index 0d597b09c..99e01366d 100644 --- a/Tests/Functional/Command/GraphDumpSchemaCommandTest.php +++ b/Tests/Functional/Command/GraphDumpSchemaCommandTest.php @@ -126,6 +126,8 @@ private function assertCommandExecution(array $input, $expectedFile, $actualFile $actual = json_decode($actual, true); $this->sortSchemaEntry($expected, 'types', 'name'); $this->sortSchemaEntry($actual, 'types', 'name'); + } elseif ('graphql' === $format && isset($_SERVER['GRAPHQLPHP_VERSION']) && '^0.11.2' === $_SERVER['GRAPHQLPHP_VERSION']) { + $expected = preg_replace('@"""(.*)"""@', '# $1', $expected); } $this->assertEquals($expected, $actual); diff --git a/Tests/Functional/Command/fixtures/schema.graphql b/Tests/Functional/Command/fixtures/schema.graphql index 97dd9e6db..6ebdece93 100644 --- a/Tests/Functional/Command/fixtures/schema.graphql +++ b/Tests/Functional/Command/fixtures/schema.graphql @@ -1,15 +1,15 @@ -# Information about pagination in a connection. +"""Information about pagination in a connection.""" type PageInfo { - # When paginating forwards, are there more items? + """When paginating forwards, are there more items?""" hasNextPage: Boolean! - # When paginating backwards, are there more items? + """When paginating backwards, are there more items?""" hasPreviousPage: Boolean! - # When paginating backwards, the cursor to continue. + """When paginating backwards, the cursor to continue.""" startCursor: String - # When paginating forwards, the cursor to continue. + """When paginating forwards, the cursor to continue.""" endCursor: String } @@ -18,49 +18,49 @@ type Query { } type User { - # the user name + """the user name""" name: String friends(after: String, first: Int, before: String, last: Int): friendConnection friendsForward(after: String, first: Int): userConnection friendsBackward(before: String, last: Int): userConnection } -# A connection to a list of items. +"""A connection to a list of items.""" type friendConnection { totalCount: Int - # Information to aid in pagination. + """Information to aid in pagination.""" pageInfo: PageInfo! - # Information to aid in pagination. + """Information to aid in pagination.""" edges: [friendEdge] } -# An edge in a connection. +"""An edge in a connection.""" type friendEdge { friendshipTime: String - # The item at the end of the edge. + """The item at the end of the edge.""" node: User - # A cursor for use in pagination. + """A cursor for use in pagination.""" cursor: String! } -# A connection to a list of items. +"""A connection to a list of items.""" type userConnection { - # Information to aid in pagination. + """Information to aid in pagination.""" pageInfo: PageInfo! - # Information to aid in pagination. + """Information to aid in pagination.""" edges: [userEdge] } -# An edge in a connection. +"""An edge in a connection.""" type userEdge { - # The item at the end of the edge. + """The item at the end of the edge.""" node: User - # A cursor for use in pagination. + """A cursor for use in pagination.""" cursor: String! } diff --git a/Tests/Functional/Upload/UploadTest.php b/Tests/Functional/Upload/UploadTest.php index ab5e2cebb..35810927c 100644 --- a/Tests/Functional/Upload/UploadTest.php +++ b/Tests/Functional/Upload/UploadTest.php @@ -1,6 +1,6 @@ expectException(InvariantViolation::class); - $this->expectExceptionMessage('Upload scalar serialization unsupported.'); $this->uploadRequest( [ 'operations' => [ diff --git a/Upload/Type/GraphQLUploadType.php b/Upload/Type/GraphQLUploadType.php index 17fdd6df2..da6265496 100644 --- a/Upload/Type/GraphQLUploadType.php +++ b/Upload/Type/GraphQLUploadType.php @@ -49,7 +49,7 @@ public function serialize($value) /** * {@inheritdoc} */ - public function parseLiteral($valueNode) + public function parseLiteral($valueNode, array $variables = null) { throw new InvariantViolation(sprintf('%s scalar literal unsupported.', $this->name)); } diff --git a/composer.json b/composer.json index 08dbea9a4..c6f098b53 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "symfony/framework-bundle": "^3.1 || ^4.0", "symfony/options-resolver": "^3.1 || ^4.0", "symfony/property-access": "^3.1 || ^4.0", - "webonyx/graphql-php": "^0.11.2" + "webonyx/graphql-php": "^0.11.2 || ^0.12.0" }, "suggest": { "nelmio/cors-bundle": "For more flexibility when using CORS prefight",