graphql 1.7.6 → 1.8.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/function_generator.rb +1 -1
- data/lib/generators/graphql/install_generator.rb +14 -8
- data/lib/generators/graphql/loader_generator.rb +1 -1
- data/lib/generators/graphql/mutation_generator.rb +6 -1
- data/lib/generators/graphql/templates/function.erb +2 -2
- data/lib/generators/graphql/templates/loader.erb +2 -2
- data/lib/generators/graphql/templates/schema.erb +1 -1
- data/lib/graphql/argument.rb +25 -19
- data/lib/graphql/backtrace/tracer.rb +16 -22
- data/lib/graphql/backtrace.rb +1 -1
- data/lib/graphql/backwards_compatibility.rb +2 -3
- data/lib/graphql/base_type.rb +31 -31
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +14 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
- data/lib/graphql/define/assign_object_field.rb +5 -12
- data/lib/graphql/deprecated_dsl.rb +42 -0
- data/lib/graphql/directive.rb +1 -0
- data/lib/graphql/enum_type.rb +3 -1
- data/lib/graphql/execution/execute.rb +21 -13
- data/lib/graphql/execution/instrumentation.rb +82 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +1 -3
- data/lib/graphql/execution/multiplex.rb +12 -29
- data/lib/graphql/execution.rb +1 -0
- data/lib/graphql/field.rb +21 -4
- data/lib/graphql/function.rb +14 -0
- data/lib/graphql/input_object_type.rb +3 -1
- data/lib/graphql/interface_type.rb +5 -3
- data/lib/graphql/internal_representation/node.rb +26 -14
- data/lib/graphql/internal_representation/visit.rb +3 -6
- data/lib/graphql/introspection/base_object.rb +16 -0
- data/lib/graphql/introspection/directive_location_enum.rb +11 -7
- data/lib/graphql/introspection/directive_type.rb +23 -16
- data/lib/graphql/introspection/dynamic_fields.rb +11 -0
- data/lib/graphql/introspection/entry_points.rb +29 -0
- data/lib/graphql/introspection/enum_value_type.rb +16 -11
- data/lib/graphql/introspection/field_type.rb +21 -12
- data/lib/graphql/introspection/input_value_type.rb +26 -23
- data/lib/graphql/introspection/schema_field.rb +7 -2
- data/lib/graphql/introspection/schema_type.rb +36 -22
- data/lib/graphql/introspection/type_by_name_field.rb +10 -2
- data/lib/graphql/introspection/type_kind_enum.rb +10 -6
- data/lib/graphql/introspection/type_type.rb +85 -23
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/introspection.rb +3 -10
- data/lib/graphql/language/block_string.rb +47 -0
- data/lib/graphql/language/document_from_schema_definition.rb +280 -0
- data/lib/graphql/language/generation.rb +3 -182
- data/lib/graphql/language/lexer.rb +144 -69
- data/lib/graphql/language/lexer.rl +15 -4
- data/lib/graphql/language/nodes.rb +141 -78
- data/lib/graphql/language/parser.rb +677 -630
- data/lib/graphql/language/parser.y +18 -12
- data/lib/graphql/language/printer.rb +361 -0
- data/lib/graphql/language/token.rb +10 -3
- data/lib/graphql/language.rb +3 -0
- data/lib/graphql/non_null_type.rb +1 -1
- data/lib/graphql/object_type.rb +1 -6
- data/lib/graphql/query/arguments.rb +63 -32
- data/lib/graphql/query/context.rb +32 -2
- data/lib/graphql/query/literal_input.rb +4 -1
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query/result.rb +1 -1
- data/lib/graphql/query/variables.rb +21 -3
- data/lib/graphql/query.rb +19 -6
- data/lib/graphql/railtie.rb +109 -0
- data/lib/graphql/relay/connection_resolve.rb +3 -0
- data/lib/graphql/relay/connection_type.rb +5 -3
- data/lib/graphql/relay/edge_type.rb +2 -1
- data/lib/graphql/relay/global_id_resolve.rb +5 -1
- data/lib/graphql/relay/mongo_relation_connection.rb +40 -0
- data/lib/graphql/relay/mutation/instrumentation.rb +1 -1
- data/lib/graphql/relay/mutation/resolve.rb +5 -1
- data/lib/graphql/relay/relation_connection.rb +14 -19
- data/lib/graphql/relay/type_extensions.rb +30 -0
- data/lib/graphql/relay.rb +2 -0
- data/lib/graphql/scalar_type.rb +14 -2
- data/lib/graphql/schema/argument.rb +92 -0
- data/lib/graphql/schema/build_from_definition.rb +64 -18
- data/lib/graphql/schema/enum.rb +85 -0
- data/lib/graphql/schema/enum_value.rb +74 -0
- data/lib/graphql/schema/field.rb +372 -0
- data/lib/graphql/schema/finder.rb +153 -0
- data/lib/graphql/schema/input_object.rb +87 -0
- data/lib/graphql/schema/interface.rb +105 -0
- data/lib/graphql/schema/introspection_system.rb +93 -0
- data/lib/graphql/schema/late_bound_type.rb +32 -0
- data/lib/graphql/schema/list.rb +32 -0
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/member/accepts_definition.rb +152 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +100 -0
- data/lib/graphql/schema/member/build_type.rb +137 -0
- data/lib/graphql/schema/member/cached_graphql_definition.rb +26 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +50 -0
- data/lib/graphql/schema/member/has_fields.rb +130 -0
- data/lib/graphql/schema/member/instrumentation.rb +115 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +34 -0
- data/lib/graphql/schema/member.rb +28 -0
- data/lib/graphql/schema/middleware_chain.rb +5 -1
- data/lib/graphql/schema/mutation.rb +138 -0
- data/lib/graphql/schema/non_null.rb +38 -0
- data/lib/graphql/schema/object.rb +81 -0
- data/lib/graphql/schema/printer.rb +33 -266
- data/lib/graphql/schema/relay_classic_mutation.rb +87 -0
- data/lib/graphql/schema/rescue_middleware.rb +8 -7
- data/lib/graphql/schema/resolver.rb +122 -0
- data/lib/graphql/schema/scalar.rb +35 -0
- data/lib/graphql/schema/traversal.rb +102 -22
- data/lib/graphql/schema/union.rb +36 -0
- data/lib/graphql/schema/validation.rb +3 -2
- data/lib/graphql/schema.rb +381 -12
- data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
- data/lib/graphql/static_validation/literal_validator.rb +16 -4
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +11 -1
- data/lib/graphql/static_validation/validation_context.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -5
- data/lib/graphql/subscriptions/instrumentation.rb +5 -1
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +90 -16
- data/lib/graphql/tracing/data_dog_tracing.rb +49 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
- data/lib/graphql/tracing/platform_tracing.rb +20 -7
- data/lib/graphql/tracing/scout_tracing.rb +2 -2
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/unresolved_type_error.rb +3 -2
- data/lib/graphql/upgrader/member.rb +894 -0
- data/lib/graphql/upgrader/schema.rb +37 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +5 -25
- data/readme.md +2 -2
- data/spec/dummy/app/channels/graphql_channel.rb +23 -2
- data/spec/dummy/log/development.log +239 -0
- data/spec/dummy/log/test.log +410 -0
- data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xYZjAnuuzgR79fcznLTQtSdh6AARxu8FcQ_J6p7L3U.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/13/13HiV12xyoQvT-1L39ZzLwMZxjyaGMiENmfw7f-QTIc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3W/3Wtf5pCWdqq0AB-iB0Y9uUNrTkruRxIEf1XFn_BETU0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5i/5iguGafb4hOn8262Kn8Q37ogNN9MxxQKGKNzHAzUcvI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8m/8mj2T6yy847Mc2Z7k3Xzh8O91hhVJt3NrPe8ASNDlIA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTQyMpr4ABZYQetsdRJ5A7S4jf1r3ie4FGOR7GZBNSs.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dq/DqJ5_yJPrP5iLlOQyTQsjAVI5FE5LCVDkED0f7GgsSo.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwDuCV-XpnCtjNkvhpJfBuxXMk0b5AD3L9eR6M-wcy0.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UL/ULdjhhb0bRuqmaG7XSZlFYzGYCXTDnqZuJBTWRlzqgw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Up/UpPNgh0yYoUsyMDh5zWqe_U6qJIyTC6-dxMMAs1vvlM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wg/Wguh-szFGTI1gaL6npYwPekMXflugRei7F_mOyRucXg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X-/X-khLYMA9mqFRPg3zAi86mREDxpKl4bdKYp3uF6WHos.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bi/BIkdhfxsezxM4q-HZ4oCNTq97WEJTigcq0tpX2cDvbY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ff/FfxmA4CMHQZT7exx0G7NS1Wpcnny0vzp-Jhc2H36bp8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gE/gEiiG4GZNy_djEjK2pHm_NgA-gyhLZhdQvo0Yt96GqE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gn/gnA9ZSqpjccNL2m8pe_jBvY6SinXlCzXDWyop83Od8s.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lO/lOAan3cMwCE_Hli6gsDML88xFNfn0nxPmvrSkW7eEOw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/M1pv8MJEPLXGLvS8QxVh3DSO9cI4mRt5FHFWdrvUj6o.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m7/m77qH7ZqH0_0SmwJbiKGDd-aLau1Dav847DC6ge46zY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjRjnjRB37lH2vrgtkdJ8Cz84__IJ978IuKTM7HcztI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/um/um1JrirR4hJhK-1rE-HywlyCi5ibgxHVrReiujZBWJM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v4/v4fwVytD7ITcE0_GDbslZEYud8a5Okm85fV1o7SDl6g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v_/v_0PAQt0iipQjFP5zjgkkk9Stnpf4VzvnMv67d1Keuw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdT9U4MKxe1PyqNjVuCKMpCl3dxGCIRJIlwUTfh2DQU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xI/xIaxut_fEIhKBDqljTNwYaADK9kj3gG0ESrfHs-5_og.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y0/y0SJOqIx2fn1SKqOkAihsQow0trRJrSIyAswufVuoA8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zgpzeaX-KZErHyGJ1aBH3ZusweNXMneVZule88XsIJI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zYFltDy-8VC-uKq2BVEiJJyYXNFvVzAKuMlR3ZIYZsk.cache +0 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/fixtures/upgrader/account.original.rb +19 -0
- data/spec/fixtures/upgrader/account.transformed.rb +20 -0
- data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
- data/spec/fixtures/upgrader/blame_range.transformed.rb +30 -0
- data/spec/fixtures/upgrader/date_time.original.rb +24 -0
- data/spec/fixtures/upgrader/date_time.transformed.rb +23 -0
- data/spec/fixtures/upgrader/delete_project.original.rb +28 -0
- data/spec/fixtures/upgrader/delete_project.transformed.rb +27 -0
- data/spec/fixtures/upgrader/gist_order_field.original.rb +14 -0
- data/spec/fixtures/upgrader/gist_order_field.transformed.rb +13 -0
- data/spec/fixtures/upgrader/increment_count.original.rb +59 -0
- data/spec/fixtures/upgrader/increment_count.transformed.rb +50 -0
- data/spec/fixtures/upgrader/photo.original.rb +10 -0
- data/spec/fixtures/upgrader/photo.transformed.rb +12 -0
- data/spec/fixtures/upgrader/release_order.original.rb +15 -0
- data/spec/fixtures/upgrader/release_order.transformed.rb +14 -0
- data/spec/fixtures/upgrader/starrable.original.rb +49 -0
- data/spec/fixtures/upgrader/starrable.transformed.rb +46 -0
- data/spec/fixtures/upgrader/subscribable.original.rb +55 -0
- data/spec/fixtures/upgrader/subscribable.transformed.rb +51 -0
- data/spec/fixtures/upgrader/type_x.original.rb +65 -0
- data/spec/fixtures/upgrader/type_x.transformed.rb +56 -0
- data/spec/generators/graphql/function_generator_spec.rb +26 -0
- data/spec/generators/graphql/install_generator_spec.rb +1 -1
- data/spec/generators/graphql/loader_generator_spec.rb +24 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
- data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
- data/spec/graphql/argument_spec.rb +21 -0
- data/spec/graphql/backtrace_spec.rb +10 -0
- data/spec/graphql/base_type_spec.rb +42 -0
- data/spec/graphql/boolean_type_spec.rb +3 -3
- data/spec/graphql/directive_spec.rb +3 -1
- data/spec/graphql/enum_type_spec.rb +18 -5
- data/spec/graphql/execution/execute_spec.rb +4 -4
- data/spec/graphql/execution/instrumentation_spec.rb +165 -0
- data/spec/graphql/execution/multiplex_spec.rb +2 -2
- data/spec/graphql/execution_error_spec.rb +18 -0
- data/spec/graphql/float_type_spec.rb +2 -2
- data/spec/graphql/id_type_spec.rb +1 -1
- data/spec/graphql/input_object_type_spec.rb +15 -2
- data/spec/graphql/int_type_spec.rb +2 -2
- data/spec/graphql/interface_type_spec.rb +12 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
- data/spec/graphql/introspection/schema_type_spec.rb +2 -0
- data/spec/graphql/language/block_string_spec.rb +70 -0
- data/spec/graphql/language/document_from_schema_definition_spec.rb +770 -0
- data/spec/graphql/language/generation_spec.rb +21 -186
- data/spec/graphql/language/lexer_spec.rb +21 -1
- data/spec/graphql/language/nodes_spec.rb +21 -12
- data/spec/graphql/language/parser_spec.rb +1 -1
- data/spec/graphql/language/printer_spec.rb +203 -0
- data/spec/graphql/object_type_spec.rb +22 -0
- data/spec/graphql/query/arguments_spec.rb +25 -15
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +2 -1
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -8
- data/spec/graphql/query/variables_spec.rb +42 -1
- data/spec/graphql/query_spec.rb +31 -5
- data/spec/graphql/rake_task_spec.rb +3 -1
- data/spec/graphql/relay/base_connection_spec.rb +1 -1
- data/spec/graphql/relay/connection_instrumentation_spec.rb +2 -2
- data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
- data/spec/graphql/relay/connection_type_spec.rb +1 -1
- data/spec/graphql/relay/mongo_relation_connection_spec.rb +474 -0
- data/spec/graphql/relay/mutation_spec.rb +9 -7
- data/spec/graphql/relay/range_add_spec.rb +5 -1
- data/spec/graphql/relay/relation_connection_spec.rb +65 -1
- data/spec/graphql/schema/argument_spec.rb +87 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +89 -5
- data/spec/graphql/schema/enum_spec.rb +74 -0
- data/spec/graphql/schema/field_spec.rb +225 -0
- data/spec/graphql/schema/finder_spec.rb +135 -0
- data/spec/graphql/schema/input_object_spec.rb +111 -0
- data/spec/graphql/schema/instrumentation_spec.rb +40 -0
- data/spec/graphql/schema/interface_spec.rb +185 -0
- data/spec/graphql/schema/introspection_system_spec.rb +39 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +111 -0
- data/spec/graphql/schema/member/build_type_spec.rb +17 -0
- data/spec/graphql/schema/member/has_fields_spec.rb +129 -0
- data/spec/graphql/schema/member/type_system_helpers_spec.rb +63 -0
- data/spec/graphql/schema/mutation_spec.rb +148 -0
- data/spec/graphql/schema/object_spec.rb +175 -0
- data/spec/graphql/schema/printer_spec.rb +111 -15
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +38 -0
- data/spec/graphql/schema/rescue_middleware_spec.rb +11 -0
- data/spec/graphql/schema/resolver_spec.rb +131 -0
- data/spec/graphql/schema/scalar_spec.rb +95 -0
- data/spec/graphql/schema/traversal_spec.rb +31 -0
- data/spec/graphql/schema/union_spec.rb +65 -0
- data/spec/graphql/schema/validation_spec.rb +1 -1
- data/spec/graphql/schema/warden_spec.rb +11 -11
- data/spec/graphql/schema_spec.rb +55 -12
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -2
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
- data/spec/graphql/string_type_spec.rb +3 -3
- data/spec/graphql/subscriptions_spec.rb +273 -184
- data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +1 -1
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
- data/spec/graphql/tracing/platform_tracing_spec.rb +60 -1
- data/spec/graphql/union_type_spec.rb +1 -1
- data/spec/graphql/upgrader/member_spec.rb +516 -0
- data/spec/graphql/upgrader/schema_spec.rb +82 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/dummy/schema.rb +53 -24
- data/spec/support/jazz.rb +544 -0
- data/spec/support/lazy_helpers.rb +21 -23
- data/spec/support/new_relic.rb +24 -0
- data/spec/support/star_trek/data.rb +109 -0
- data/spec/support/star_trek/schema.rb +388 -0
- data/spec/support/star_wars/data.rb +6 -7
- data/spec/support/star_wars/schema.rb +127 -171
- metadata +233 -11
- data/lib/graphql/introspection/arguments_field.rb +0 -7
- data/lib/graphql/introspection/enum_values_field.rb +0 -18
- data/lib/graphql/introspection/fields_field.rb +0 -13
- data/lib/graphql/introspection/input_fields_field.rb +0 -12
- data/lib/graphql/introspection/interfaces_field.rb +0 -11
- data/lib/graphql/introspection/of_type_field.rb +0 -6
- data/lib/graphql/introspection/possible_types_field.rb +0 -11
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe GraphQL::Schema::Member::HasFields do
|
5
|
+
module SuperTest
|
6
|
+
class BaseObject < GraphQL::Schema::Object
|
7
|
+
end
|
8
|
+
|
9
|
+
module BaseInterface
|
10
|
+
include GraphQL::Schema::Interface
|
11
|
+
end
|
12
|
+
|
13
|
+
module InterfaceWithFloatField
|
14
|
+
include BaseInterface
|
15
|
+
field :float, Float, null: false
|
16
|
+
def float
|
17
|
+
# This should call the default implementation
|
18
|
+
super * 0.5
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module SubInterfaceWithFloatField
|
23
|
+
include InterfaceWithFloatField
|
24
|
+
def float
|
25
|
+
# This should call `InterfaceWithFloatField#float`
|
26
|
+
super * 0.1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class ObjectWithFloatField < BaseObject
|
31
|
+
implements InterfaceWithFloatField
|
32
|
+
end
|
33
|
+
|
34
|
+
class ObjectWithSubFloatField < BaseObject
|
35
|
+
implements SubInterfaceWithFloatField
|
36
|
+
end
|
37
|
+
|
38
|
+
module InterfaceWithStringField
|
39
|
+
include BaseInterface
|
40
|
+
field :string, String, null: false
|
41
|
+
def string
|
42
|
+
# Return a literal value to ensure this method was called
|
43
|
+
"here's a string"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ObjectWithStringField < BaseObject
|
48
|
+
implements InterfaceWithStringField
|
49
|
+
def string
|
50
|
+
# This should call to `InterfaceWithStringField#string`
|
51
|
+
super.upcase
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class SubObjectWithStringField < ObjectWithStringField
|
56
|
+
def string
|
57
|
+
# This should call to `ObjectWithStringField#string`
|
58
|
+
super.reverse
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class SubSubObjectWithStringField < SubObjectWithStringField
|
63
|
+
field :string, String, null: false
|
64
|
+
end
|
65
|
+
|
66
|
+
class Query < BaseObject
|
67
|
+
field :int, Integer, null: false
|
68
|
+
def int
|
69
|
+
# This should call default resolution
|
70
|
+
super * 2
|
71
|
+
end
|
72
|
+
|
73
|
+
field :string1, ObjectWithStringField, null: false, method: :object
|
74
|
+
field :string2, SubObjectWithStringField, null: false, method: :object
|
75
|
+
field :string3, SubSubObjectWithStringField, null: false, method: :object
|
76
|
+
field :float1, ObjectWithFloatField, null: false, method: :object
|
77
|
+
field :float2, ObjectWithSubFloatField, null: false, method: :object
|
78
|
+
end
|
79
|
+
|
80
|
+
class Schema < GraphQL::Schema
|
81
|
+
query(Query)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "Calling super in field methods" do
|
86
|
+
# Test that calling `super` in field methods "works", which means:
|
87
|
+
# - If there is a super method in the user-created hierarchy (either a class or module), it is called
|
88
|
+
# This is tested by putting random transformations in method bodies,
|
89
|
+
# then asserting that they are called.
|
90
|
+
# - If there's no user-defined super method, it calls the built-in default behavior
|
91
|
+
# This is tested by putting values in the `root_value` hash.
|
92
|
+
# The default behavior is to fetch hash values by key, so we assert that
|
93
|
+
# those values are subject to the specified transformations.
|
94
|
+
|
95
|
+
describe "Object methods" do
|
96
|
+
it "may call super to default implementation" do
|
97
|
+
res = SuperTest::Schema.execute("{ int }", root_value: { int: 4 })
|
98
|
+
assert_equal 8, res["data"]["int"]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "may call super to interface method" do
|
102
|
+
res = SuperTest::Schema.execute(" { string1 { string } }", root_value: {})
|
103
|
+
assert_equal "HERE'S A STRING", res["data"]["string1"]["string"]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "may call super to superclass method" do
|
107
|
+
res = SuperTest::Schema.execute(" { string2 { string } }", root_value: {})
|
108
|
+
assert_equal "GNIRTS A S'EREH", res["data"]["string2"]["string"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "can get a super method from a newly-added field" do
|
112
|
+
res = SuperTest::Schema.execute(" { string3 { string } }", root_value: {})
|
113
|
+
assert_equal "GNIRTS A S'EREH", res["data"]["string3"]["string"]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "Interface methods" do
|
118
|
+
it "may call super to interface method" do
|
119
|
+
res = SuperTest::Schema.execute(" { float1 { float } }", root_value: { float: 6.0 })
|
120
|
+
assert_equal 3.0, res["data"]["float1"]["float"]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "may call super to superclass method" do
|
124
|
+
res = SuperTest::Schema.execute(" { float2 { float } }", root_value: { float: 6.0 })
|
125
|
+
assert_in_delta 0.001, 0.3, res["data"]["float2"]["float"]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe GraphQL::Schema::Member::TypeSystemHelpers do
|
5
|
+
let(:object) {
|
6
|
+
Class.new(GraphQL::Schema::Object) do
|
7
|
+
graphql_name "Thing"
|
8
|
+
|
9
|
+
field :int, Integer, null: true
|
10
|
+
field :int2, Integer, null: false
|
11
|
+
field :int_list, [Integer], null: true
|
12
|
+
field :int_list2, [Integer], null: false
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
let(:int_field) { object.fields["int"] }
|
17
|
+
let(:int2_field) { object.fields["int2"] }
|
18
|
+
let(:int_list_field) { object.fields["intList"] }
|
19
|
+
let(:int_list2_field) { object.fields["intList2"] }
|
20
|
+
|
21
|
+
describe "#list?" do
|
22
|
+
it "is true for lists, including non-null lists, otherwise false" do
|
23
|
+
assert int_list_field.type.list?
|
24
|
+
assert int_list2_field.type.list?
|
25
|
+
refute int_field.type.list?
|
26
|
+
refute int2_field.type.list?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#non_null?" do
|
31
|
+
it "is true for required types" do
|
32
|
+
assert int2_field.type.non_null?
|
33
|
+
assert int_list2_field.type.non_null?
|
34
|
+
refute int_field.type.non_null?
|
35
|
+
refute int_list_field.type.non_null?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#kind" do
|
40
|
+
let(:pairs) {{
|
41
|
+
GraphQL::Schema::Object => "OBJECT",
|
42
|
+
GraphQL::Schema::Union => "UNION",
|
43
|
+
GraphQL::Schema::Interface => "INTERFACE",
|
44
|
+
GraphQL::Schema::Enum => "ENUM",
|
45
|
+
GraphQL::Schema::InputObject => "INPUT_OBJECT",
|
46
|
+
GraphQL::Schema::Scalar => "SCALAR",
|
47
|
+
}}
|
48
|
+
it "returns the TypeKind instance" do
|
49
|
+
pairs.each do |type_class, type_kind_name|
|
50
|
+
type = if type_class.is_a?(Class)
|
51
|
+
Class.new(type_class)
|
52
|
+
else
|
53
|
+
Module.new { include(type_class) }
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal type_kind_name, type.kind.name
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_equal "LIST", GraphQL::Schema::Object.to_list_type.kind.name
|
60
|
+
assert_equal "NON_NULL", GraphQL::Schema::Object.to_non_null_type.kind.name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
# Make sure that `!` has no effect
|
5
|
+
using GraphQL::DeprecatedDSL
|
6
|
+
|
7
|
+
describe GraphQL::Schema::Mutation do
|
8
|
+
let(:mutation) { Jazz::AddInstrument }
|
9
|
+
after do
|
10
|
+
Jazz::Models.reset
|
11
|
+
end
|
12
|
+
|
13
|
+
it "Doesn't override !" do
|
14
|
+
assert_equal false, !mutation
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "definition" do
|
18
|
+
it "passes along description" do
|
19
|
+
assert_equal "Register a new musical instrument in the database", mutation.field_options[:description]
|
20
|
+
assert_equal "Autogenerated return type of AddInstrument", mutation.payload_type.description
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "argument prepare" do
|
25
|
+
it "calls methods on the mutation, uses `as:`" do
|
26
|
+
query_str = 'mutation { prepareInput(input: 4) }'
|
27
|
+
res = Jazz::Schema.execute(query_str)
|
28
|
+
assert_equal 16, res["data"]["prepareInput"], "It's squared by the prepare method"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "a derived field" do
|
33
|
+
it "has a reference to the mutation" do
|
34
|
+
f = GraphQL::Schema::Field.from_options(name: "x", **mutation.field_options)
|
35
|
+
assert_equal mutation, f.mutation
|
36
|
+
|
37
|
+
# Make sure it's also present in the schema
|
38
|
+
f2 = Jazz::Schema.find("Mutation.addInstrument")
|
39
|
+
assert_equal mutation, f2.mutation
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".payload_type" do
|
44
|
+
it "has a reference to the mutation" do
|
45
|
+
assert_equal mutation, mutation.payload_type.mutation
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe ".field" do
|
50
|
+
it "raises a nice error when called without args" do
|
51
|
+
err = assert_raises(ArgumentError) { mutation.field }
|
52
|
+
assert_includes err.message, "Use `mutation: Jazz::AddInstrument` to attach this mutation instead."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe ".object_class" do
|
57
|
+
it "can override & inherit the parent class" do
|
58
|
+
obj_class = Class.new(GraphQL::Schema::Object)
|
59
|
+
mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
60
|
+
object_class(obj_class)
|
61
|
+
end
|
62
|
+
mutation_subclass = Class.new(mutation_class)
|
63
|
+
|
64
|
+
assert_equal(GraphQL::Schema::Object, GraphQL::Schema::Mutation.object_class)
|
65
|
+
assert_equal(obj_class, mutation_class.object_class)
|
66
|
+
assert_equal(obj_class, mutation_subclass.object_class) end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe ".argument_class" do
|
70
|
+
it "can override & inherit the parent class" do
|
71
|
+
arg_class = Class.new(GraphQL::Schema::Argument)
|
72
|
+
mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
73
|
+
argument_class(arg_class)
|
74
|
+
end
|
75
|
+
|
76
|
+
mutation_subclass = Class.new(mutation_class)
|
77
|
+
|
78
|
+
assert_equal(GraphQL::Schema::Argument, GraphQL::Schema::Mutation.argument_class)
|
79
|
+
assert_equal(arg_class, mutation_class.argument_class)
|
80
|
+
assert_equal(arg_class, mutation_subclass.argument_class)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "evaluation" do
|
85
|
+
it "runs mutations" do
|
86
|
+
query_str = <<-GRAPHQL
|
87
|
+
mutation {
|
88
|
+
addInstrument(name: "Trombone", family: BRASS) {
|
89
|
+
instrument {
|
90
|
+
name
|
91
|
+
family
|
92
|
+
}
|
93
|
+
entries {
|
94
|
+
name
|
95
|
+
}
|
96
|
+
ee
|
97
|
+
}
|
98
|
+
}
|
99
|
+
GRAPHQL
|
100
|
+
|
101
|
+
response = Jazz::Schema.execute(query_str)
|
102
|
+
assert_equal "Trombone", response["data"]["addInstrument"]["instrument"]["name"]
|
103
|
+
assert_equal "BRASS", response["data"]["addInstrument"]["instrument"]["family"]
|
104
|
+
assert_equal "GraphQL::Query::Context::ExecutionErrors", response["data"]["addInstrument"]["ee"]
|
105
|
+
assert_equal 7, response["data"]["addInstrument"]["entries"].size
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe ".null" do
|
110
|
+
it "overrides whether or not the field can be null" do
|
111
|
+
non_nullable_mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
112
|
+
graphql_name "Thing1"
|
113
|
+
null(false)
|
114
|
+
end
|
115
|
+
|
116
|
+
nullable_mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
117
|
+
graphql_name "Thing2"
|
118
|
+
null(true)
|
119
|
+
end
|
120
|
+
|
121
|
+
default_mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
122
|
+
graphql_name "Thing3"
|
123
|
+
end
|
124
|
+
|
125
|
+
assert default_mutation_class.field_options[:null]
|
126
|
+
assert nullable_mutation_class.field_options[:null]
|
127
|
+
refute non_nullable_mutation_class.field_options[:null]
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should inherit and override in subclasses" do
|
131
|
+
base_mutation = Class.new(GraphQL::Schema::Mutation) do
|
132
|
+
null(false)
|
133
|
+
end
|
134
|
+
|
135
|
+
inheriting_mutation = Class.new(base_mutation) do
|
136
|
+
graphql_name "Thing"
|
137
|
+
end
|
138
|
+
|
139
|
+
override_mutation = Class.new(base_mutation) do
|
140
|
+
graphql_name "Thing2"
|
141
|
+
null(true)
|
142
|
+
end
|
143
|
+
|
144
|
+
assert_equal false, inheriting_mutation.field_options[:null]
|
145
|
+
assert override_mutation.field_options[:null]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe GraphQL::Schema::Object do
|
5
|
+
describe "class attributes" do
|
6
|
+
let(:object_class) { Jazz::Ensemble }
|
7
|
+
it "tells type data" do
|
8
|
+
assert_equal "Ensemble", object_class.graphql_name
|
9
|
+
assert_equal "A group of musicians playing together", object_class.description
|
10
|
+
assert_equal 6, object_class.fields.size
|
11
|
+
assert_equal 3, object_class.interfaces.size
|
12
|
+
# Compatibility methods are delegated to the underlying BaseType
|
13
|
+
assert object_class.respond_to?(:connection_type)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "inherits fields and interfaces" do
|
17
|
+
new_object_class = Class.new(object_class) do
|
18
|
+
field :newField, String, null: true
|
19
|
+
field :name, String, description: "The new description", null: true
|
20
|
+
end
|
21
|
+
|
22
|
+
# one more than the parent class
|
23
|
+
assert_equal 7, new_object_class.fields.size
|
24
|
+
# inherited interfaces are present
|
25
|
+
assert_equal 3, new_object_class.interfaces.size
|
26
|
+
# The new field is present
|
27
|
+
assert new_object_class.fields.key?("newField")
|
28
|
+
# The overridden field is present:
|
29
|
+
name_field = new_object_class.fields["name"]
|
30
|
+
assert_equal "The new description", name_field.description
|
31
|
+
end
|
32
|
+
|
33
|
+
it "inherits name and description" do
|
34
|
+
# Manually assign a name since `.name` isn't populated for dynamic classes
|
35
|
+
new_subclass_1 = Class.new(object_class) do
|
36
|
+
graphql_name "NewSubclass"
|
37
|
+
end
|
38
|
+
new_subclass_2 = Class.new(new_subclass_1)
|
39
|
+
assert_equal "NewSubclass", new_subclass_1.graphql_name
|
40
|
+
assert_equal "NewSubclass", new_subclass_2.graphql_name
|
41
|
+
assert_equal object_class.description, new_subclass_2.description
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should take Ruby name (without Type suffix) as default graphql name" do
|
45
|
+
TestingClassType = Class.new(GraphQL::Schema::Object)
|
46
|
+
assert_equal "TestingClass", TestingClassType.graphql_name
|
47
|
+
end
|
48
|
+
|
49
|
+
it "raise on anonymous class without declared graphql name" do
|
50
|
+
anonymous_class = Class.new(GraphQL::Schema::Object)
|
51
|
+
assert_raises NotImplementedError do
|
52
|
+
anonymous_class.graphql_name
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "wrapping a Hash" do
|
58
|
+
it "automatically looks up symbol and string keys" do
|
59
|
+
query_str = <<-GRAPHQL
|
60
|
+
{
|
61
|
+
hashyEnsemble {
|
62
|
+
musicians { name }
|
63
|
+
formedAt
|
64
|
+
}
|
65
|
+
}
|
66
|
+
GRAPHQL
|
67
|
+
res = Jazz::Schema.execute(query_str)
|
68
|
+
ensemble = res["data"]["hashyEnsemble"]
|
69
|
+
assert_equal ["Jerry Garcia"], ensemble["musicians"].map { |m| m["name"] }
|
70
|
+
assert_equal "May 5, 1965", ensemble["formedAt"]
|
71
|
+
end
|
72
|
+
|
73
|
+
it "works with strings and symbols" do
|
74
|
+
query_str = <<-GRAPHQL
|
75
|
+
{
|
76
|
+
hashByString { falsey }
|
77
|
+
hashBySym { falsey }
|
78
|
+
}
|
79
|
+
GRAPHQL
|
80
|
+
res = Jazz::Schema.execute(query_str)
|
81
|
+
assert_equal false, res["data"]["hashByString"]["falsey"]
|
82
|
+
assert_equal false, res["data"]["hashBySym"]["falsey"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe ".to_graphql_type" do
|
87
|
+
let(:obj_type) { Jazz::Ensemble.to_graphql }
|
88
|
+
it "returns a matching GraphQL::ObjectType" do
|
89
|
+
assert_equal "Ensemble", obj_type.name
|
90
|
+
assert_equal "A group of musicians playing together", obj_type.description
|
91
|
+
assert_equal 6, obj_type.all_fields.size
|
92
|
+
|
93
|
+
name_field = obj_type.all_fields[2]
|
94
|
+
assert_equal "name", name_field.name
|
95
|
+
assert_equal GraphQL::STRING_TYPE.to_non_null_type, name_field.type
|
96
|
+
assert_equal nil, name_field.description
|
97
|
+
end
|
98
|
+
|
99
|
+
it "has a custom implementation" do
|
100
|
+
assert_equal obj_type.metadata[:config], :configged
|
101
|
+
end
|
102
|
+
|
103
|
+
it "uses the custom field class" do
|
104
|
+
query_str = <<-GRAPHQL
|
105
|
+
{
|
106
|
+
ensembles { upcaseName }
|
107
|
+
}
|
108
|
+
GRAPHQL
|
109
|
+
|
110
|
+
res = Jazz::Schema.execute(query_str)
|
111
|
+
assert_equal ["BELA FLECK AND THE FLECKTONES", "ROBERT GLASPER EXPERIMENT"], res["data"]["ensembles"].map { |e| e["upcaseName"] }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
describe "in queries" do
|
117
|
+
after {
|
118
|
+
Jazz::Models.reset
|
119
|
+
}
|
120
|
+
|
121
|
+
it "returns data" do
|
122
|
+
query_str = <<-GRAPHQL
|
123
|
+
{
|
124
|
+
ensembles { name }
|
125
|
+
instruments { name }
|
126
|
+
}
|
127
|
+
GRAPHQL
|
128
|
+
res = Jazz::Schema.execute(query_str)
|
129
|
+
expected_ensembles = [
|
130
|
+
{"name" => "Bela Fleck and the Flecktones"},
|
131
|
+
{"name" => "ROBERT GLASPER Experiment"},
|
132
|
+
]
|
133
|
+
assert_equal expected_ensembles, res["data"]["ensembles"]
|
134
|
+
assert_equal({"name" => "Banjo"}, res["data"]["instruments"].first)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "does mutations" do
|
138
|
+
mutation_str = <<-GRAPHQL
|
139
|
+
mutation AddEnsemble($name: String!) {
|
140
|
+
addEnsemble(input: { name: $name }) {
|
141
|
+
id
|
142
|
+
}
|
143
|
+
}
|
144
|
+
GRAPHQL
|
145
|
+
|
146
|
+
query_str = <<-GRAPHQL
|
147
|
+
query($id: ID!) {
|
148
|
+
find(id: $id) {
|
149
|
+
... on Ensemble {
|
150
|
+
name
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
GRAPHQL
|
155
|
+
|
156
|
+
res = Jazz::Schema.execute(mutation_str, variables: { name: "Miles Davis Quartet" })
|
157
|
+
new_id = res["data"]["addEnsemble"]["id"]
|
158
|
+
|
159
|
+
res2 = Jazz::Schema.execute(query_str, variables: { id: new_id })
|
160
|
+
assert_equal "Miles Davis Quartet", res2["data"]["find"]["name"]
|
161
|
+
end
|
162
|
+
|
163
|
+
it "initializes root wrappers once" do
|
164
|
+
query_str = " { oid1: objectId oid2: objectId }"
|
165
|
+
res = Jazz::Schema.execute(query_str)
|
166
|
+
assert_equal res["data"]["oid1"], res["data"]["oid2"]
|
167
|
+
end
|
168
|
+
|
169
|
+
it "skips fields properly" do
|
170
|
+
query_str = "{ find(id: \"MagicalSkipId\") { __typename } }"
|
171
|
+
res = Jazz::Schema.execute(query_str)
|
172
|
+
assert_equal({"data" => nil }, res.to_h)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|