graphql 1.8.7 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +2 -1
- data/lib/generators/graphql/scalar_generator.rb +20 -0
- data/lib/generators/graphql/templates/base_scalar.erb +4 -0
- data/lib/generators/graphql/templates/scalar.erb +13 -0
- data/lib/graphql/analysis/ast/analyzer.rb +62 -0
- data/lib/graphql/analysis/ast/field_usage.rb +28 -0
- data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -0
- data/lib/graphql/analysis/ast/max_query_depth.rb +18 -0
- data/lib/graphql/analysis/ast/query_complexity.rb +114 -0
- data/lib/graphql/analysis/ast/query_depth.rb +66 -0
- data/lib/graphql/analysis/ast/visitor.rb +255 -0
- data/lib/graphql/analysis/ast.rb +82 -0
- data/lib/graphql/analysis.rb +1 -0
- data/lib/graphql/argument.rb +5 -0
- data/lib/graphql/authorization.rb +1 -0
- data/lib/graphql/backwards_compatibility.rb +1 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -2
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -6
- data/lib/graphql/dig.rb +19 -0
- data/lib/graphql/directive/include_directive.rb +1 -7
- data/lib/graphql/directive/skip_directive.rb +1 -8
- data/lib/graphql/directive.rb +13 -1
- data/lib/graphql/enum_type.rb +8 -0
- data/lib/graphql/execution/execute.rb +36 -17
- data/lib/graphql/execution/instrumentation.rb +2 -0
- data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
- data/lib/graphql/execution/interpreter/hash_response.rb +46 -0
- data/lib/graphql/execution/interpreter/resolve.rb +58 -0
- data/lib/graphql/execution/interpreter/runtime.rb +597 -0
- data/lib/graphql/execution/interpreter.rb +99 -0
- data/lib/graphql/execution/lazy.rb +8 -1
- data/lib/graphql/execution/lookahead.rb +351 -0
- data/lib/graphql/execution/multiplex.rb +37 -29
- data/lib/graphql/execution.rb +2 -0
- data/lib/graphql/execution_error.rb +1 -1
- data/lib/graphql/field.rb +1 -7
- data/lib/graphql/integer_encoding_error.rb +12 -0
- data/lib/graphql/internal_representation/rewrite.rb +127 -142
- data/lib/graphql/introspection/dynamic_fields.rb +8 -2
- data/lib/graphql/introspection/entry_points.rb +11 -6
- data/lib/graphql/introspection/enum_value_type.rb +4 -0
- data/lib/graphql/introspection/schema_type.rb +7 -2
- data/lib/graphql/introspection/type_type.rb +9 -5
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/block_string.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +10 -7
- data/lib/graphql/language/lexer.rb +55 -36
- data/lib/graphql/language/lexer.rl +8 -3
- data/lib/graphql/language/nodes.rb +440 -362
- data/lib/graphql/language/parser.rb +56 -56
- data/lib/graphql/language/parser.y +12 -12
- data/lib/graphql/language/printer.rb +2 -2
- data/lib/graphql/language/visitor.rb +158 -15
- data/lib/graphql/language.rb +0 -1
- data/lib/graphql/literal_validation_error.rb +6 -0
- data/lib/graphql/query/arguments.rb +3 -2
- data/lib/graphql/query/arguments_cache.rb +1 -1
- data/lib/graphql/query/context.rb +14 -5
- data/lib/graphql/query/executor.rb +1 -1
- data/lib/graphql/query/result.rb +1 -1
- data/lib/graphql/query/validation_pipeline.rb +35 -11
- data/lib/graphql/query/variable_validation_error.rb +10 -1
- data/lib/graphql/query.rb +16 -2
- data/lib/graphql/relay/base_connection.rb +2 -0
- data/lib/graphql/relay/connection_instrumentation.rb +3 -1
- data/lib/graphql/relay/connection_resolve.rb +1 -1
- data/lib/graphql/relay/node.rb +2 -28
- data/lib/graphql/relay/relation_connection.rb +1 -1
- data/lib/graphql/schema/argument.rb +13 -5
- data/lib/graphql/schema/base_64_encoder.rb +4 -4
- data/lib/graphql/schema/build_from_definition.rb +2 -4
- data/lib/graphql/schema/default_type_error.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +66 -0
- data/lib/graphql/schema/directive/include.rb +25 -0
- data/lib/graphql/schema/directive/skip.rb +25 -0
- data/lib/graphql/schema/directive/transform.rb +48 -0
- data/lib/graphql/schema/directive.rb +103 -0
- data/lib/graphql/schema/enum_value.rb +3 -2
- data/lib/graphql/schema/field/connection_extension.rb +50 -0
- data/lib/graphql/schema/field/scope_extension.rb +18 -0
- data/lib/graphql/schema/field.rb +273 -64
- data/lib/graphql/schema/field_extension.rb +69 -0
- data/lib/graphql/schema/input_object.rb +16 -8
- data/lib/graphql/schema/interface.rb +1 -0
- data/lib/graphql/schema/loader.rb +22 -16
- data/lib/graphql/schema/member/base_dsl_methods.rb +8 -2
- data/lib/graphql/schema/member/build_type.rb +33 -1
- data/lib/graphql/schema/member/has_arguments.rb +6 -2
- data/lib/graphql/schema/member/has_fields.rb +18 -70
- data/lib/graphql/schema/member/has_path.rb +25 -0
- data/lib/graphql/schema/member/instrumentation.rb +10 -7
- data/lib/graphql/schema/member.rb +2 -0
- data/lib/graphql/schema/mutation.rb +6 -48
- data/lib/graphql/schema/non_null.rb +5 -1
- data/lib/graphql/schema/object.rb +18 -4
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +42 -9
- data/lib/graphql/schema/resolver/has_payload_type.rb +65 -0
- data/lib/graphql/schema/resolver.rb +45 -20
- data/lib/graphql/schema/subscription.rb +97 -0
- data/lib/graphql/schema/traversal.rb +11 -7
- data/lib/graphql/schema.rb +186 -38
- data/lib/graphql/static_validation/all_rules.rb +3 -2
- data/lib/graphql/static_validation/base_visitor.rb +199 -0
- data/lib/graphql/static_validation/default_visitor.rb +15 -0
- data/lib/graphql/static_validation/definition_dependencies.rb +62 -68
- data/lib/graphql/static_validation/{message.rb → error.rb} +11 -11
- data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
- data/lib/graphql/static_validation/literal_validator.rb +54 -11
- data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +87 -16
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +31 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +11 -11
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +52 -8
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +35 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -15
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +19 -14
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +17 -19
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +30 -14
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +356 -29
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +20 -13
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +37 -29
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +25 -17
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +12 -10
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +7 -11
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +16 -16
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +21 -14
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +10 -14
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +30 -30
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +25 -17
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +17 -18
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +47 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +10 -14
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +28 -17
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +35 -27
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +15 -14
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -30
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +18 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +73 -65
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
- data/lib/graphql/static_validation/validation_context.rb +8 -51
- data/lib/graphql/static_validation/validator.rb +23 -15
- data/lib/graphql/static_validation.rb +5 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -2
- data/lib/graphql/subscriptions/event.rb +28 -5
- data/lib/graphql/subscriptions/subscription_root.rb +66 -0
- data/lib/graphql/subscriptions.rb +16 -2
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +0 -1
- data/lib/graphql/tracing/appsignal_tracing.rb +1 -1
- data/lib/graphql/tracing/data_dog_tracing.rb +1 -1
- data/lib/graphql/tracing/new_relic_tracing.rb +3 -3
- data/lib/graphql/tracing/platform_tracing.rb +17 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +1 -1
- data/lib/graphql/tracing/scout_tracing.rb +1 -1
- data/lib/graphql/tracing/skylight_tracing.rb +3 -3
- data/lib/graphql/tracing.rb +8 -8
- data/lib/graphql/types/float.rb +1 -1
- data/lib/graphql/types/int.rb +11 -2
- data/lib/graphql/types/iso_8601_date_time.rb +15 -1
- data/lib/graphql/types/relay/base_connection.rb +15 -1
- data/lib/graphql/types/relay/node.rb +0 -1
- data/lib/graphql/types/relay/node_field.rb +43 -0
- data/lib/graphql/types/relay/nodes_field.rb +45 -0
- data/lib/graphql/types/relay.rb +2 -0
- data/lib/graphql/unauthorized_error.rb +4 -0
- data/lib/graphql/unauthorized_field_error.rb +23 -0
- data/lib/graphql/upgrader/member.rb +5 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +6 -1
- data/readme.md +7 -7
- data/spec/dummy/Gemfile +1 -1
- data/spec/dummy/Gemfile.lock +157 -0
- data/spec/dummy/app/channels/graphql_channel.rb +22 -11
- data/spec/dummy/config/locales/en.yml +1 -1
- data/spec/dummy/log/test.log +199 -0
- data/spec/dummy/test/test_helper.rb +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/graphql/analysis/analyze_query_spec.rb +1 -1
- data/spec/graphql/analysis/ast/field_usage_spec.rb +51 -0
- data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +120 -0
- data/spec/graphql/analysis/ast/max_query_depth_spec.rb +114 -0
- data/spec/graphql/analysis/ast/query_complexity_spec.rb +299 -0
- data/spec/graphql/analysis/ast/query_depth_spec.rb +108 -0
- data/spec/graphql/analysis/ast_spec.rb +269 -0
- data/spec/graphql/authorization_spec.rb +120 -23
- data/spec/graphql/base_type_spec.rb +6 -4
- data/spec/graphql/enum_type_spec.rb +6 -1
- data/spec/graphql/execution/execute_spec.rb +9 -9
- data/spec/graphql/execution/instrumentation_spec.rb +19 -0
- data/spec/graphql/execution/interpreter_spec.rb +485 -0
- data/spec/graphql/execution/lazy_spec.rb +67 -1
- data/spec/graphql/execution/lookahead_spec.rb +363 -0
- data/spec/graphql/execution/multiplex_spec.rb +31 -3
- data/spec/graphql/execution/typecast_spec.rb +20 -20
- data/spec/graphql/execution_error_spec.rb +110 -96
- data/spec/graphql/field_spec.rb +1 -1
- data/spec/graphql/input_object_type_spec.rb +13 -352
- data/spec/graphql/int_type_spec.rb +19 -0
- data/spec/graphql/interface_type_spec.rb +4 -4
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -0
- data/spec/graphql/introspection/input_value_type_spec.rb +1 -1
- data/spec/graphql/introspection/type_type_spec.rb +1 -2
- data/spec/graphql/language/document_from_schema_definition_spec.rb +2 -2
- data/spec/graphql/language/lexer_spec.rb +72 -3
- data/spec/graphql/language/nodes_spec.rb +20 -0
- data/spec/graphql/language/printer_spec.rb +18 -6
- data/spec/graphql/language/visitor_spec.rb +320 -14
- data/spec/graphql/non_null_type_spec.rb +1 -1
- data/spec/graphql/object_type_spec.rb +32 -27
- data/spec/graphql/query/arguments_spec.rb +21 -0
- data/spec/graphql/query/context_spec.rb +28 -0
- data/spec/graphql/query/executor_spec.rb +40 -36
- data/spec/graphql/query_spec.rb +12 -6
- data/spec/graphql/schema/argument_spec.rb +35 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +144 -29
- data/spec/graphql/schema/catchall_middleware_spec.rb +16 -15
- data/spec/graphql/schema/directive/feature_spec.rb +81 -0
- data/spec/graphql/schema/directive/transform_spec.rb +39 -0
- data/spec/graphql/schema/enum_spec.rb +12 -3
- data/spec/graphql/schema/enum_value_spec.rb +11 -0
- data/spec/graphql/schema/field_extension_spec.rb +115 -0
- data/spec/graphql/schema/field_spec.rb +47 -7
- data/spec/graphql/schema/input_object_spec.rb +95 -0
- data/spec/graphql/schema/instrumentation_spec.rb +3 -0
- data/spec/graphql/schema/interface_spec.rb +8 -2
- data/spec/graphql/schema/introspection_system_spec.rb +9 -1
- data/spec/graphql/schema/loader_spec.rb +5 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +4 -0
- data/spec/graphql/schema/member/build_type_spec.rb +46 -0
- data/spec/graphql/schema/member/scoped_spec.rb +19 -3
- data/spec/graphql/schema/mutation_spec.rb +5 -3
- data/spec/graphql/schema/object_spec.rb +9 -1
- data/spec/graphql/schema/printer_spec.rb +255 -93
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +133 -0
- data/spec/graphql/schema/resolver_spec.rb +173 -9
- data/spec/graphql/schema/scalar_spec.rb +6 -0
- data/spec/graphql/schema/subscription_spec.rb +416 -0
- data/spec/graphql/schema/traversal_spec.rb +10 -10
- data/spec/graphql/schema/type_expression_spec.rb +2 -2
- data/spec/graphql/schema/union_spec.rb +7 -0
- data/spec/graphql/schema/validation_spec.rb +1 -1
- data/spec/graphql/schema/warden_spec.rb +145 -88
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +213 -73
- data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +72 -29
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +10 -5
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -5
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +131 -5
- data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +22 -2
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +13 -4
- data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +58 -0
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +14 -7
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +14 -7
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +8 -4
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +8 -4
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +23 -3
- data/spec/graphql/static_validation/type_stack_spec.rb +10 -19
- data/spec/graphql/static_validation/validator_spec.rb +50 -2
- data/spec/graphql/subscriptions_spec.rb +27 -16
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +16 -0
- data/spec/graphql/tracing/platform_tracing_spec.rb +59 -37
- data/spec/graphql/tracing/prometheus_tracing_spec.rb +3 -0
- data/spec/graphql/tracing/skylight_tracing_spec.rb +16 -0
- data/spec/graphql/types/iso_8601_date_time_spec.rb +29 -2
- data/spec/graphql/union_type_spec.rb +2 -2
- data/spec/graphql/upgrader/member_spec.rb +67 -0
- data/spec/{graphql → integration/mongoid/graphql}/relay/mongo_relation_connection_spec.rb +11 -22
- data/spec/integration/mongoid/spec_helper.rb +2 -0
- data/spec/{support → integration/mongoid}/star_trek/data.rb +0 -0
- data/spec/{support → integration/mongoid}/star_trek/schema.rb +56 -34
- data/spec/{support/star_wars → integration/rails}/data.rb +1 -0
- data/spec/{support → integration/rails/generators}/base_generator_test.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/enum_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/install_generator_spec.rb +1 -1
- data/spec/{generators → integration/rails/generators}/graphql/interface_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/loader_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/mutation_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/object_generator_spec.rb +0 -0
- data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +28 -0
- data/spec/{generators → integration/rails/generators}/graphql/union_generator_spec.rb +0 -0
- data/spec/integration/rails/graphql/input_object_type_spec.rb +364 -0
- data/spec/{graphql → integration/rails/graphql}/query/variables_spec.rb +7 -7
- data/spec/{graphql → integration/rails/graphql}/relay/array_connection_spec.rb +9 -9
- data/spec/{graphql → integration/rails/graphql}/relay/base_connection_spec.rb +11 -3
- data/spec/{graphql → integration/rails/graphql}/relay/connection_instrumentation_spec.rb +19 -22
- data/spec/{graphql → integration/rails/graphql}/relay/connection_resolve_spec.rb +16 -0
- data/spec/{graphql → integration/rails/graphql}/relay/connection_type_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/edge_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/mutation_spec.rb +48 -0
- data/spec/{graphql → integration/rails/graphql}/relay/node_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/page_info_spec.rb +22 -22
- data/spec/{graphql → integration/rails/graphql}/relay/range_add_spec.rb +4 -4
- data/spec/{graphql → integration/rails/graphql}/relay/relation_connection_spec.rb +56 -27
- data/spec/{graphql → integration/rails/graphql}/schema_spec.rb +15 -11
- data/spec/{graphql → integration/rails/graphql}/tracing/active_support_notifications_tracing_spec.rb +16 -9
- data/spec/integration/rails/spec_helper.rb +25 -0
- data/spec/integration/tmp/app/graphql/types/family_type.rb +9 -0
- data/spec/spec_helper.rb +23 -39
- data/spec/support/dummy/data.rb +20 -17
- data/spec/support/dummy/schema.rb +315 -305
- data/spec/support/error_bubbling_helpers.rb +23 -0
- data/spec/support/jazz.rb +213 -46
- data/spec/support/lazy_helpers.rb +69 -27
- data/spec/support/new_relic.rb +3 -0
- data/spec/support/skylight.rb +3 -0
- data/spec/support/star_wars/schema.rb +131 -81
- data/spec/support/static_validation_helpers.rb +9 -5
- metadata +418 -261
- data/lib/graphql/language/comments.rb +0 -45
- data/lib/graphql/static_validation/arguments_validator.rb +0 -50
- data/spec/graphql/schema/member/has_fields_spec.rb +0 -129
- data/spec/rails_dependency_sanity_spec.rb +0 -14
@@ -7,40 +7,58 @@ module Dummy
|
|
7
7
|
GraphQL::Field.accepts_definitions(joins: GraphQL::Define.assign_metadata_key(:joins))
|
8
8
|
GraphQL::BaseType.accepts_definitions(class_names: GraphQL::Define.assign_metadata_key(:class_names))
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
description "Something that comes from somewhere"
|
13
|
-
field :origin, !types.String, "Place the thing comes from"
|
10
|
+
class BaseField < GraphQL::Schema::Field
|
11
|
+
accepts_definition :joins
|
14
12
|
end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
description "Something you can eat, yum"
|
19
|
-
field :fatContent, !types.Float, "Percentage which is fat"
|
20
|
-
field :origin, !types.String, "Place the edible comes from"
|
21
|
-
field :selfAsEdible, EdibleInterface, resolve: ->(o, a, c) { o }
|
14
|
+
module BaseInterface
|
15
|
+
include GraphQL::Schema::Interface
|
22
16
|
end
|
23
17
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
resolve_type ->(obj, ctx) { MilkType }
|
18
|
+
class BaseObject < GraphQL::Schema::Object
|
19
|
+
field_class BaseField
|
20
|
+
accepts_definition :class_names
|
28
21
|
end
|
29
22
|
|
30
|
-
|
31
|
-
name "AnimalProduct"
|
32
|
-
description "Comes from an animal, no joke"
|
33
|
-
field :source, !DairyAnimalEnum, "Animal which produced this product"
|
23
|
+
class BaseUnion < GraphQL::Schema::Union
|
34
24
|
end
|
35
25
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
class BaseEnum < GraphQL::Schema::Enum
|
27
|
+
end
|
28
|
+
|
29
|
+
class BaseInputObject < GraphQL::Schema::InputObject
|
30
|
+
end
|
31
|
+
|
32
|
+
class BaseScalar < GraphQL::Schema::Scalar
|
33
|
+
end
|
34
|
+
|
35
|
+
module LocalProduct
|
36
|
+
include BaseInterface
|
37
|
+
description "Something that comes from somewhere"
|
38
|
+
field :origin, String, null: false,
|
39
|
+
description: "Place the thing comes from"
|
40
|
+
end
|
41
|
+
|
42
|
+
module Edible
|
43
|
+
include BaseInterface
|
44
|
+
description "Something you can eat, yum"
|
45
|
+
field :fat_content, Float, null: false, description: "Percentage which is fat"
|
46
|
+
field :origin, String, null: false, description: "Place the edible comes from"
|
47
|
+
field :self_as_edible, Edible, null: true
|
48
|
+
def self_as_edible
|
49
|
+
object
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module EdibleAsMilk
|
54
|
+
include Edible
|
55
|
+
description "Milk :+1:"
|
56
|
+
def self.resolve_type(obj, ctx)
|
57
|
+
Milk
|
58
|
+
end
|
40
59
|
end
|
41
60
|
|
42
|
-
|
43
|
-
name "DairyAnimal"
|
61
|
+
class DairyAnimal < BaseEnum
|
44
62
|
description "An animal which can yield milk"
|
45
63
|
value("COW", "Animal with black and white spots", value: 1)
|
46
64
|
value("DONKEY", "Animal with fur", value: :donkey)
|
@@ -50,433 +68,425 @@ module Dummy
|
|
50
68
|
value("YAK", "Animal with long hair", deprecation_reason: "Out of fashion")
|
51
69
|
end
|
52
70
|
|
53
|
-
|
54
|
-
|
71
|
+
module AnimalProduct
|
72
|
+
include BaseInterface
|
73
|
+
description "Comes from an animal, no joke"
|
74
|
+
field :source, DairyAnimal, "Animal which produced this product", null: false
|
75
|
+
end
|
76
|
+
|
77
|
+
class Cheese < BaseObject
|
55
78
|
class_names ["Cheese"]
|
56
79
|
description "Cultured dairy product"
|
57
|
-
|
80
|
+
implements Edible
|
81
|
+
implements EdibleAsMilk
|
82
|
+
implements AnimalProduct
|
83
|
+
implements LocalProduct
|
58
84
|
|
59
|
-
|
60
|
-
field :
|
61
|
-
field :
|
62
|
-
field :origin, !types.String, "Place the cheese comes from"
|
85
|
+
field :id, Int, "Unique identifier", null: false
|
86
|
+
field :flavor, String, "Kind of Cheese", null: false
|
87
|
+
field :origin, String, "Place the cheese comes from", null: false
|
63
88
|
|
64
|
-
field :source,
|
65
|
-
"Animal which produced the milk for this cheese"
|
89
|
+
field :source, DairyAnimal,
|
90
|
+
"Animal which produced the milk for this cheese",
|
91
|
+
null: false
|
66
92
|
|
67
|
-
|
68
|
-
field :similarCheese, CheeseType, "Cheeses like this one", property: :this_should_be_overriden do
|
93
|
+
field :similar_cheese, Cheese, "Cheeses like this one", null: true do
|
69
94
|
# metadata test
|
70
95
|
joins [:cheeses, :milks]
|
71
|
-
argument :source,
|
72
|
-
argument :nullableSource,
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
96
|
+
argument :source, [DairyAnimal], required: true
|
97
|
+
argument :nullableSource, [DairyAnimal], required: false, default_value: [1]
|
98
|
+
end
|
99
|
+
|
100
|
+
def similar_cheese(source:, nullable_source:)
|
101
|
+
# get the strings out:
|
102
|
+
sources = source
|
103
|
+
if sources.include?("YAK")
|
104
|
+
raise NoSuchDairyError.new("No cheeses are made from Yak milk!")
|
105
|
+
else
|
106
|
+
CHEESES.values.find { |cheese| sources.include?(cheese.source) }
|
107
|
+
end
|
82
108
|
end
|
83
109
|
|
84
|
-
field :
|
85
|
-
argument :source,
|
86
|
-
resolve ->(t, a, c) { raise("NotImplemented") }
|
110
|
+
field :nullable_cheese, Cheese, "Cheeses like this one", null: true do
|
111
|
+
argument :source, [DairyAnimal], required: false
|
87
112
|
end
|
113
|
+
def nullable_cheese; raise("NotImplemented"); end
|
88
114
|
|
89
|
-
field :
|
90
|
-
argument :source,
|
91
|
-
resolve ->(t, a, c) { raise("NotImplemented") }
|
115
|
+
field :deeply_nullable_cheese, Cheese, "Cheeses like this one", null: true do
|
116
|
+
argument :source, [[DairyAnimal, null: true], null: true], required: false
|
92
117
|
end
|
118
|
+
def deeply_nullable_cheese; raise("NotImplemented"); end
|
93
119
|
|
94
120
|
# Keywords can be used for definition methods
|
95
|
-
field :
|
96
|
-
|
97
|
-
|
121
|
+
field :fat_content,
|
122
|
+
type: GraphQL::FLOAT_TYPE,
|
123
|
+
null: false,
|
98
124
|
description: "Percentage which is milkfat",
|
99
125
|
deprecation_reason: "Diet fashion has changed"
|
100
126
|
end
|
101
127
|
|
102
|
-
|
103
|
-
name "Milk"
|
128
|
+
class Milk < BaseObject
|
104
129
|
description "Dairy beverage"
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
field :executionError do
|
116
|
-
type GraphQL::STRING_TYPE
|
117
|
-
resolve ->(t, a, c) { raise(GraphQL::ExecutionError, "There was an execution error") }
|
130
|
+
implements Edible
|
131
|
+
implements EdibleAsMilk
|
132
|
+
implements AnimalProduct
|
133
|
+
implements LocalProduct
|
134
|
+
|
135
|
+
field :id, ID, null: false
|
136
|
+
field :source, DairyAnimal, null: false, description: "Animal which produced this milk"
|
137
|
+
field :origin, String, null: false, description: "Place the milk comes from"
|
138
|
+
field :flavors, [String, null: true], null: true, description: "Chocolate, Strawberry, etc" do
|
139
|
+
argument :limit, Int, required: false
|
118
140
|
end
|
119
141
|
|
120
|
-
|
121
|
-
|
142
|
+
def flavors(limit: nil)
|
143
|
+
limit ? object.flavors.first(limit) : object.flavors
|
122
144
|
end
|
145
|
+
|
146
|
+
field :execution_error, String, null: true
|
147
|
+
def execution_error; raise(GraphQL::ExecutionError, "There was an execution error"); end
|
148
|
+
|
149
|
+
field :all_dairy, ["Dummy::DairyProduct", null: true], null: true
|
150
|
+
def all_dairy; CHEESES.values + MILKS.values; end
|
123
151
|
end
|
124
152
|
|
125
|
-
|
126
|
-
|
127
|
-
|
153
|
+
class Beverage < BaseUnion
|
154
|
+
description "Something you can drink"
|
155
|
+
possible_types Milk
|
156
|
+
end
|
157
|
+
|
158
|
+
module Sweetener
|
159
|
+
include BaseInterface
|
160
|
+
field :sweetness, Integer, null: true
|
128
161
|
end
|
129
162
|
|
130
163
|
# No actual data; This type is an "orphan", only accessible through Interfaces
|
131
|
-
|
132
|
-
name "Honey"
|
164
|
+
class Honey < BaseObject
|
133
165
|
description "Sweet, dehydrated bee barf"
|
134
|
-
field :
|
135
|
-
|
166
|
+
field :flower_type, String, "What flower this honey came from", null: true
|
167
|
+
implements Edible
|
168
|
+
implements AnimalProduct
|
169
|
+
implements Sweetener
|
136
170
|
end
|
137
171
|
|
138
|
-
|
139
|
-
name "Dairy"
|
172
|
+
class Dairy < BaseObject
|
140
173
|
description "A farm where milk is harvested and cheese is produced"
|
141
|
-
field :id,
|
142
|
-
field :cheese,
|
143
|
-
field :milks,
|
174
|
+
field :id, ID, null: false
|
175
|
+
field :cheese, Cheese, null: true
|
176
|
+
field :milks, [Milk, null: true], null: true
|
144
177
|
end
|
145
178
|
|
146
|
-
|
147
|
-
name "MaybeNull"
|
179
|
+
class MaybeNull < BaseObject
|
148
180
|
description "An object whose fields return nil"
|
149
|
-
field :cheese,
|
181
|
+
field :cheese, Cheese, null: true
|
150
182
|
end
|
151
183
|
|
152
|
-
|
153
|
-
name "TracingScalar"
|
184
|
+
class TracingScalar < BaseObject
|
154
185
|
description "An object which has traced scalars"
|
155
186
|
|
156
|
-
field :
|
157
|
-
field :
|
158
|
-
field :
|
187
|
+
field :trace_nil, Integer, null: true
|
188
|
+
field :trace_false, Integer, null: true, trace: false
|
189
|
+
field :trace_true, Integer, null: true, trace: true
|
159
190
|
end
|
160
191
|
|
161
|
-
|
162
|
-
name "DairyProduct"
|
192
|
+
class DairyProduct < BaseUnion
|
163
193
|
description "Kinds of food made from milk"
|
164
194
|
# Test that these forms of declaration still work:
|
165
|
-
possible_types
|
195
|
+
possible_types "Dummy::Milk", Cheese
|
166
196
|
end
|
167
197
|
|
168
|
-
|
169
|
-
name "Cow"
|
198
|
+
class Cow < BaseObject
|
170
199
|
description "A bovine animal that produces milk"
|
171
|
-
field :id,
|
172
|
-
field :name,
|
173
|
-
field :last_produced_dairy,
|
200
|
+
field :id, ID, null: false
|
201
|
+
field :name, String, null: true
|
202
|
+
field :last_produced_dairy, DairyProduct, null: true
|
174
203
|
|
175
|
-
field :
|
176
|
-
|
177
|
-
resolve ->(t, a, c) { nil }
|
178
|
-
end
|
204
|
+
field :cant_be_null_but_is, String, null: false
|
205
|
+
def cant_be_null_but_is; nil; end
|
179
206
|
|
180
|
-
field :
|
181
|
-
|
182
|
-
resolve ->(t, a, c) { raise GraphQL::ExecutionError, "BOOM" }
|
183
|
-
end
|
207
|
+
field :cant_be_null_but_raises_execution_error, String, null: false
|
208
|
+
def cant_be_null_but_raises_execution_error; raise(GraphQL::ExecutionError, "BOOM"); end
|
184
209
|
end
|
185
210
|
|
186
|
-
|
187
|
-
name "Goat"
|
211
|
+
class Goat < BaseObject
|
188
212
|
description "An caprinae animal that produces milk"
|
189
|
-
field :id,
|
190
|
-
field :name,
|
191
|
-
field :last_produced_dairy,
|
213
|
+
field :id, ID, null: false
|
214
|
+
field :name, String, null: true
|
215
|
+
field :last_produced_dairy, DairyProduct, null: true
|
192
216
|
end
|
193
217
|
|
194
|
-
|
195
|
-
name "Animal"
|
218
|
+
class Animal < BaseUnion
|
196
219
|
description "Species of living things"
|
197
|
-
possible_types
|
220
|
+
possible_types Cow, Goat
|
198
221
|
end
|
199
222
|
|
200
|
-
|
201
|
-
name "AnimalAsCow"
|
223
|
+
class AnimalAsCow < BaseUnion
|
202
224
|
description "All animals go mooooo!"
|
203
|
-
possible_types
|
204
|
-
resolve_type
|
205
|
-
|
206
|
-
|
225
|
+
possible_types Cow
|
226
|
+
def self.resolve_type(obj, ctx)
|
227
|
+
Cow
|
228
|
+
end
|
207
229
|
end
|
208
230
|
|
209
|
-
|
210
|
-
|
231
|
+
class ResourceOrder < BaseInputObject
|
232
|
+
graphql_name "ResourceOrderType"
|
211
233
|
description "Properties used to determine ordering"
|
212
234
|
|
213
|
-
argument :direction,
|
214
|
-
|
215
|
-
end
|
216
|
-
}
|
235
|
+
argument :direction, String, required: true, description: "ASC or DESC"
|
236
|
+
end
|
217
237
|
|
218
|
-
|
219
|
-
name "DairyProductInput"
|
238
|
+
class DairyProductInput < BaseInputObject
|
220
239
|
description "Properties for finding a dairy product"
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
240
|
+
argument :source, DairyAnimal, required: true, description: "Where it came from"
|
241
|
+
argument :origin_dairy, String, required: false, description: "Dairy which produced it", default_value: "Sugar Hollow Dairy"
|
242
|
+
argument :fat_content, Float, required: false, description: "How much fat it has", default_value: 0.3
|
243
|
+
argument :organic, Boolean, required: false, default_value: false
|
244
|
+
argument :order_by, ResourceOrder, required: false, default_value: { direction: "ASC" }, camelize: false
|
245
|
+
end
|
227
246
|
|
228
|
-
|
229
|
-
|
230
|
-
|
247
|
+
class DeepNonNull < BaseObject
|
248
|
+
field :non_null_int, Integer, null: false do
|
249
|
+
argument :returning, Integer, required: false
|
231
250
|
end
|
232
|
-
|
233
|
-
|
234
|
-
input_field :organic, types.Boolean, default_value: false
|
235
|
-
|
236
|
-
input_field :order_by, -> { ResourceOrderType }, default_value: { direction: 'ASC' }
|
237
|
-
}
|
238
|
-
|
239
|
-
DeepNonNullType = GraphQL::ObjectType.define do
|
240
|
-
name "DeepNonNull"
|
241
|
-
field :nonNullInt, !types.Int do
|
242
|
-
argument :returning, types.Int
|
243
|
-
resolve ->(obj, args, ctx) { args.returning }
|
251
|
+
def non_null_int(returning: nil)
|
252
|
+
returning
|
244
253
|
end
|
245
254
|
|
246
|
-
field :
|
247
|
-
|
248
|
-
end
|
255
|
+
field :deep_non_null, DeepNonNull, null: false
|
256
|
+
def deep_non_null; :deep_non_null; end
|
249
257
|
end
|
250
258
|
|
251
|
-
|
252
|
-
name "Time"
|
259
|
+
class Time < BaseScalar
|
253
260
|
description "Time since epoch in seconds"
|
254
261
|
|
255
|
-
coerce_input
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
raise GraphQL::CoercionError, 'cannot coerce to Float'
|
260
|
-
end
|
262
|
+
def self.coerce_input(value, ctx)
|
263
|
+
Time.at(Float(value))
|
264
|
+
rescue ArgumentError
|
265
|
+
raise GraphQL::CoercionError, 'cannot coerce to Float'
|
261
266
|
end
|
262
267
|
|
263
|
-
coerce_result
|
268
|
+
def self.coerce_result(value, ctx)
|
269
|
+
value.to_f
|
270
|
+
end
|
264
271
|
end
|
265
272
|
|
266
|
-
class FetchItem < GraphQL::
|
267
|
-
|
273
|
+
class FetchItem < GraphQL::Schema::Resolver
|
274
|
+
class << self
|
275
|
+
attr_accessor :data
|
276
|
+
end
|
268
277
|
|
269
|
-
def
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
278
|
+
def self.build(type:, data:, id_type: "Int")
|
279
|
+
Class.new(self) do
|
280
|
+
self.data = data
|
281
|
+
type(type, null: true)
|
282
|
+
description("Find a #{type.name} by id")
|
283
|
+
argument :id, id_type, required: true
|
284
|
+
end
|
274
285
|
end
|
275
286
|
|
276
|
-
def
|
277
|
-
id_string =
|
278
|
-
_id, item =
|
287
|
+
def resolve(id:)
|
288
|
+
id_string = id.to_s # Cheese has Int type, Milk has ID type :(
|
289
|
+
_id, item = self.class.data.find { |item_id, _item| item_id.to_s == id_string }
|
279
290
|
item
|
280
291
|
end
|
281
292
|
end
|
282
293
|
|
283
|
-
class GetSingleton < GraphQL::
|
284
|
-
|
294
|
+
class GetSingleton < GraphQL::Schema::Resolver
|
295
|
+
class << self
|
296
|
+
attr_accessor :data
|
297
|
+
end
|
285
298
|
|
286
|
-
def
|
287
|
-
|
288
|
-
|
289
|
-
|
299
|
+
def self.build(type:, data:)
|
300
|
+
Class.new(self) do
|
301
|
+
description("Find the only #{type.name}")
|
302
|
+
type(type, null: true)
|
303
|
+
self.data = data
|
304
|
+
end
|
290
305
|
end
|
291
306
|
|
292
|
-
def
|
293
|
-
|
307
|
+
def resolve
|
308
|
+
self.class.data
|
294
309
|
end
|
295
310
|
end
|
296
311
|
|
297
|
-
|
298
|
-
|
299
|
-
description "
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
312
|
+
class DairyAppQuery < BaseObject
|
313
|
+
graphql_name "Query"
|
314
|
+
description "Query root of the system"
|
315
|
+
# Returns `root_value:`
|
316
|
+
field :root, String, null: true
|
317
|
+
def root
|
318
|
+
object
|
319
|
+
end
|
320
|
+
field :cheese, resolver: FetchItem.build(type: Cheese, data: CHEESES)
|
321
|
+
field :milk, resolver: FetchItem.build(type: Milk, data: MILKS, id_type: "ID")
|
322
|
+
field :dairy, resolver: GetSingleton.build(type: Dairy, data: DAIRY)
|
323
|
+
field :from_source, [Cheese, null: true], null: true, description: "Cheese from source" do
|
324
|
+
argument :source, DairyAnimal, required: false, default_value: 1
|
325
|
+
end
|
326
|
+
def from_source(source:)
|
327
|
+
CHEESES.values.select { |c| c.source == source }
|
328
|
+
end
|
305
329
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
resolve ->(t, a, c) { MILKS[1] }
|
311
|
-
end
|
330
|
+
field :favorite_edible, Edible, null: true, description: "My favorite food"
|
331
|
+
def favorite_edible
|
332
|
+
MILKS[1]
|
333
|
+
end
|
312
334
|
|
313
|
-
|
314
|
-
|
315
|
-
description "Query root of the system"
|
316
|
-
field :root, types.String do
|
317
|
-
resolve ->(root_value, args, c) { root_value }
|
318
|
-
end
|
319
|
-
field :cheese, function: FetchItem.new(type: CheeseType, data: CHEESES)
|
320
|
-
field :milk, function: FetchItem.new(type: MilkType, data: MILKS, id_type: !types.ID)
|
321
|
-
field :dairy, function: GetSingleton.new(type: DairyType, data: DAIRY)
|
322
|
-
field :fromSource, &SourceFieldDefn
|
323
|
-
field :favoriteEdible, FavoriteFieldDefn
|
324
|
-
field :cow, function: GetSingleton.new(type: CowType, data: COWS[1])
|
325
|
-
field :searchDairy do
|
335
|
+
field :cow, resolver: GetSingleton.build(type: Cow, data: COWS[1])
|
336
|
+
field :search_dairy, DairyProduct, null: false do
|
326
337
|
description "Find dairy products matching a description"
|
327
|
-
type !DairyProductUnion
|
328
338
|
# This is a list just for testing 😬
|
329
|
-
argument :product,
|
330
|
-
argument :
|
331
|
-
resolve ->(t, args, c) {
|
332
|
-
source = args["product"][0][:source] # String or Sym is ok
|
333
|
-
products = CHEESES.values + MILKS.values
|
334
|
-
if !source.nil?
|
335
|
-
products = products.select { |pr| pr.source == source }
|
336
|
-
end
|
337
|
-
products.first
|
338
|
-
}
|
339
|
+
argument :product, [DairyProductInput, null: true], required: false, default_value: [{source: "SHEEP"}]
|
340
|
+
argument :expires_after, Time, required: false
|
339
341
|
end
|
340
342
|
|
341
|
-
|
342
|
-
|
343
|
+
def search_dairy(product:, expires_after: nil)
|
344
|
+
source = product[0][:source]
|
345
|
+
products = CHEESES.values + MILKS.values
|
346
|
+
if !source.nil?
|
347
|
+
products = products.select { |pr| pr.source == source }
|
348
|
+
end
|
349
|
+
products.first
|
343
350
|
end
|
344
351
|
|
345
|
-
field :
|
346
|
-
|
352
|
+
field :all_animal, [Animal, null: true], null: false
|
353
|
+
def all_animal
|
354
|
+
COWS.values + GOATS.values
|
347
355
|
end
|
348
356
|
|
349
|
-
field :
|
350
|
-
argument :executionErrorAtIndex, types.Int
|
351
|
-
resolve ->(obj, args, ctx) {
|
352
|
-
result = CHEESES.values + MILKS.values
|
353
|
-
result[args.executionErrorAtIndex] = GraphQL::ExecutionError.new("missing dairy") if args.executionErrorAtIndex
|
354
|
-
result
|
355
|
-
}
|
356
|
-
end
|
357
|
+
field :all_animal_as_cow, [AnimalAsCow, null: true], null: false, resolver_method: :all_animal
|
357
358
|
|
358
|
-
field :
|
359
|
-
|
359
|
+
field :all_dairy, [DairyProduct, null: true], null: true do
|
360
|
+
argument :execution_error_at_index, Integer, required: false
|
361
|
+
end
|
362
|
+
def all_dairy(execution_error_at_index: nil)
|
363
|
+
result = CHEESES.values + MILKS.values
|
364
|
+
if execution_error_at_index
|
365
|
+
result[execution_error_at_index] = GraphQL::ExecutionError.new("missing dairy")
|
366
|
+
end
|
367
|
+
result
|
360
368
|
end
|
361
369
|
|
362
|
-
field :
|
363
|
-
|
370
|
+
field :all_edible, [Edible, null: true], null: true
|
371
|
+
def all_edible
|
372
|
+
CHEESES.values + MILKS.values
|
364
373
|
end
|
365
374
|
|
366
|
-
field :
|
367
|
-
|
368
|
-
|
369
|
-
|
375
|
+
field :all_edible_as_milk, [EdibleAsMilk, null: true], null: true, resolver_method: :all_edible
|
376
|
+
|
377
|
+
field :error, String, null: true, description: "Raise an error"
|
378
|
+
def error
|
379
|
+
raise("This error was raised on purpose")
|
370
380
|
end
|
371
381
|
|
372
|
-
field :
|
373
|
-
|
374
|
-
|
382
|
+
field :execution_error, String, null: true
|
383
|
+
def execution_error
|
384
|
+
raise(GraphQL::ExecutionError, "There was an execution error")
|
375
385
|
end
|
376
386
|
|
377
|
-
field :
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
return 0
|
382
|
-
}
|
387
|
+
field :value_with_execution_error, Integer, null: false, extras: [:execution_errors]
|
388
|
+
def value_with_execution_error(execution_errors:)
|
389
|
+
execution_errors.add("Could not fetch latest value")
|
390
|
+
0
|
383
391
|
end
|
384
392
|
|
385
|
-
field :
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
393
|
+
field :multiple_errors_on_non_nullable_field, String, null: false
|
394
|
+
def multiple_errors_on_non_nullable_field
|
395
|
+
[
|
396
|
+
GraphQL::ExecutionError.new("This is an error message for some error."),
|
397
|
+
GraphQL::ExecutionError.new("This is another error message for a different error.")
|
398
|
+
]
|
391
399
|
end
|
392
400
|
|
393
|
-
field :
|
394
|
-
|
395
|
-
|
396
|
-
GraphQL::ExecutionError.new("Permission Denied!", options: { "code" => "permission_denied" })
|
397
|
-
}
|
401
|
+
field :execution_error_with_options, Integer, null: true
|
402
|
+
def execution_error_with_options
|
403
|
+
GraphQL::ExecutionError.new("Permission Denied!", options: { "code" => "permission_denied" })
|
398
404
|
end
|
399
405
|
|
400
|
-
field :
|
401
|
-
|
402
|
-
|
403
|
-
GraphQL::ExecutionError.new("Permission Denied!", extensions: { "code" => "permission_denied" })
|
404
|
-
}
|
406
|
+
field :execution_error_with_extensions, Integer, null: true
|
407
|
+
def execution_error_with_extensions
|
408
|
+
GraphQL::ExecutionError.new("Permission Denied!", extensions: { "code" => "permission_denied" })
|
405
409
|
end
|
406
410
|
|
407
411
|
# To test possibly-null fields
|
408
|
-
field :
|
409
|
-
|
412
|
+
field :maybe_null, MaybeNull, null: true
|
413
|
+
def maybe_null
|
414
|
+
OpenStruct.new(cheese: nil)
|
410
415
|
end
|
411
416
|
|
412
|
-
field :
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
end
|
417
|
+
field :tracing_scalar, TracingScalar, null: true
|
418
|
+
def tracing_scalar
|
419
|
+
OpenStruct.new(
|
420
|
+
trace_nil: 2,
|
421
|
+
trace_false: 3,
|
422
|
+
trace_true: 5,
|
423
|
+
)
|
420
424
|
end
|
421
425
|
|
422
|
-
field :
|
423
|
-
|
424
|
-
end
|
426
|
+
field :deep_non_null, DeepNonNull, null: false
|
427
|
+
def deep_non_null; :deep_non_null; end
|
425
428
|
end
|
426
429
|
|
427
430
|
GLOBAL_VALUES = []
|
428
431
|
|
429
|
-
|
430
|
-
|
431
|
-
input_field :values, !types[!types.Int]
|
432
|
+
class ReplaceValuesInput < BaseInputObject
|
433
|
+
argument :values, [Integer], required: true
|
432
434
|
end
|
433
435
|
|
434
|
-
|
435
|
-
name :pushValue
|
436
|
-
type !types[!types.Int]
|
437
|
-
description("Push a value onto a global array :D")
|
438
|
-
argument :value, !types.Int, as: :val
|
439
|
-
resolve ->(o, args, ctx) {
|
440
|
-
GLOBAL_VALUES << args.val
|
441
|
-
GLOBAL_VALUES
|
442
|
-
}
|
443
|
-
end
|
444
|
-
|
445
|
-
class DairyAppMutationType < GraphQL::Schema::Object
|
436
|
+
class DairyAppMutation < BaseObject
|
446
437
|
graphql_name "Mutation"
|
447
438
|
description "The root for mutations in this schema"
|
448
|
-
|
449
|
-
|
439
|
+
field :push_value, [Integer], null: false, description: "Push a value onto a global array :D" do
|
440
|
+
argument :value, Integer, required: true, as: :val
|
441
|
+
end
|
442
|
+
def push_value(val:)
|
443
|
+
GLOBAL_VALUES << val
|
444
|
+
GLOBAL_VALUES
|
445
|
+
end
|
450
446
|
|
451
447
|
field :replaceValues, [Integer], "Replace the global array with new values", null: false do
|
452
|
-
argument :input,
|
448
|
+
argument :input, ReplaceValuesInput, required: true
|
453
449
|
end
|
454
450
|
|
455
451
|
def replace_values(input:)
|
456
452
|
GLOBAL_VALUES.clear
|
457
|
-
GLOBAL_VALUES.concat(input[
|
453
|
+
GLOBAL_VALUES.concat(input[:values])
|
458
454
|
GLOBAL_VALUES
|
459
455
|
end
|
460
456
|
end
|
461
457
|
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
resolve ->(o, a, c) { "Test" }
|
466
|
-
end
|
458
|
+
class Subscription < BaseObject
|
459
|
+
field :test, String, null: true
|
460
|
+
def test; "Test"; end
|
467
461
|
end
|
468
462
|
|
469
463
|
class Schema < GraphQL::Schema
|
470
|
-
query
|
471
|
-
mutation
|
472
|
-
subscription
|
464
|
+
query DairyAppQuery
|
465
|
+
mutation DairyAppMutation
|
466
|
+
subscription Subscription
|
473
467
|
max_depth 5
|
474
|
-
|
468
|
+
# TODO why is `.graphql_definition` required here?
|
469
|
+
orphan_types Honey, Beverage.graphql_definition
|
475
470
|
|
476
471
|
rescue_from(NoSuchDairyError) { |err| err.message }
|
477
472
|
|
478
473
|
def self.resolve_type(type, obj, ctx)
|
479
474
|
Schema.types[obj.class.name.split("::").last]
|
480
475
|
end
|
476
|
+
|
477
|
+
# This is used to confirm that the hook is called:
|
478
|
+
MAGIC_INT_COERCE_VALUE = -1
|
479
|
+
|
480
|
+
def self.type_error(err, ctx)
|
481
|
+
if err.is_a?(GraphQL::IntegerEncodingError) && err.integer_value == 99**99
|
482
|
+
MAGIC_INT_COERCE_VALUE
|
483
|
+
else
|
484
|
+
super
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
if TESTING_INTERPRETER
|
489
|
+
use GraphQL::Execution::Interpreter
|
490
|
+
end
|
481
491
|
end
|
482
492
|
end
|