rails-graphql 0.2.1 → 1.0.0.beta
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/ext/console.rb +18 -0
- data/ext/extconf.h +3 -0
- data/ext/extconf.rb +1 -54
- data/ext/gql_parser.c +646 -0
- data/ext/shared.c +482 -0
- data/ext/shared.h +177 -0
- data/lib/gql_parser.so +0 -0
- data/lib/rails/graphql/adapters/mysql_adapter.rb +59 -0
- data/lib/rails/graphql/adapters/pg_adapter.rb +25 -22
- data/lib/rails/graphql/adapters/sqlite_adapter.rb +17 -14
- data/lib/rails/graphql/alternative/field_set.rb +36 -0
- data/lib/rails/graphql/alternative/mutation.rb +17 -0
- data/lib/rails/graphql/alternative/query.rb +93 -0
- data/lib/rails/graphql/alternative/subscription.rb +17 -0
- data/lib/rails/graphql/alternative.rb +20 -0
- data/lib/rails/graphql/argument.rb +21 -24
- data/lib/rails/graphql/callback.rb +24 -9
- data/lib/rails/graphql/collectors/hash_collector.rb +14 -6
- data/lib/rails/graphql/collectors/idented_collector.rb +10 -7
- data/lib/rails/graphql/collectors/json_collector.rb +22 -17
- data/lib/rails/graphql/collectors.rb +4 -4
- data/lib/rails/graphql/config.rb +130 -15
- data/lib/rails/graphql/directive/cached_directive.rb +33 -0
- data/lib/rails/graphql/directive/deprecated_directive.rb +10 -10
- data/lib/rails/graphql/directive/include_directive.rb +5 -4
- data/lib/rails/graphql/directive/skip_directive.rb +5 -4
- data/lib/rails/graphql/directive.rb +118 -63
- data/lib/rails/graphql/errors.rb +33 -4
- data/lib/rails/graphql/event.rb +16 -5
- data/lib/rails/graphql/field/authorized_field.rb +19 -3
- data/lib/rails/graphql/field/input_field.rb +11 -10
- data/lib/rails/graphql/field/mutation_field.rb +42 -7
- data/lib/rails/graphql/field/output_field.rb +102 -13
- data/lib/rails/graphql/field/proxied_field.rb +31 -22
- data/lib/rails/graphql/field/resolved_field.rb +26 -24
- data/lib/rails/graphql/field/scoped_config.rb +10 -4
- data/lib/rails/graphql/field/subscription_field.rb +140 -0
- data/lib/rails/graphql/field/typed_field.rb +43 -22
- data/lib/rails/graphql/field.rb +70 -56
- data/lib/rails/graphql/global_id.rb +85 -0
- data/lib/rails/graphql/helpers/attribute_delegator.rb +5 -5
- data/lib/rails/graphql/helpers/inherited_collection/array.rb +50 -0
- data/lib/rails/graphql/helpers/inherited_collection/base.rb +43 -0
- data/lib/rails/graphql/helpers/inherited_collection/hash.rb +87 -0
- data/lib/rails/graphql/helpers/inherited_collection.rb +25 -76
- data/lib/rails/graphql/helpers/instantiable.rb +15 -0
- data/lib/rails/graphql/helpers/leaf_from_ar.rb +7 -7
- data/lib/rails/graphql/helpers/registerable.rb +44 -62
- data/lib/rails/graphql/helpers/unregisterable.rb +16 -0
- data/lib/rails/graphql/helpers/with_arguments.rb +31 -27
- data/lib/rails/graphql/helpers/with_assignment.rb +6 -6
- data/lib/rails/graphql/helpers/with_callbacks.rb +25 -8
- data/lib/rails/graphql/helpers/with_description.rb +71 -0
- data/lib/rails/graphql/helpers/with_directives.rb +54 -30
- data/lib/rails/graphql/helpers/with_events.rb +21 -23
- data/lib/rails/graphql/helpers/with_fields.rb +76 -22
- data/lib/rails/graphql/helpers/with_global_id.rb +22 -0
- data/lib/rails/graphql/helpers/with_name.rb +43 -0
- data/lib/rails/graphql/helpers/with_namespace.rb +7 -4
- data/lib/rails/graphql/helpers/with_owner.rb +8 -7
- data/lib/rails/graphql/helpers/with_schema_fields.rb +137 -55
- data/lib/rails/graphql/helpers/with_validator.rb +9 -9
- data/lib/rails/graphql/helpers.rb +10 -3
- data/lib/rails/graphql/introspection.rb +43 -36
- data/lib/rails/graphql/railtie.rb +88 -33
- data/lib/rails/graphql/railties/base_generator.rb +3 -9
- data/lib/rails/graphql/railties/channel.rb +157 -0
- data/lib/rails/graphql/railties/controller.rb +62 -17
- data/lib/rails/graphql/railties/controller_runtime.rb +5 -5
- data/lib/rails/graphql/railties/log_subscriber.rb +81 -14
- data/lib/rails/graphql/request/arguments.rb +24 -49
- data/lib/rails/graphql/request/backtrace.rb +191 -0
- data/lib/rails/graphql/request/component/field.rb +86 -65
- data/lib/rails/graphql/request/component/fragment.rb +72 -24
- data/lib/rails/graphql/request/component/operation/subscription.rb +164 -4
- data/lib/rails/graphql/request/component/operation.rb +63 -31
- data/lib/rails/graphql/request/component/spread.rb +68 -25
- data/lib/rails/graphql/request/component/typename.rb +27 -12
- data/lib/rails/graphql/request/component.rb +75 -36
- data/lib/rails/graphql/request/context.rb +18 -8
- data/lib/rails/graphql/request/errors.rb +16 -6
- data/lib/rails/graphql/request/event.rb +19 -8
- data/lib/rails/graphql/request/helpers/directives.rb +68 -27
- data/lib/rails/graphql/request/helpers/selection_set.rb +51 -25
- data/lib/rails/graphql/request/helpers/value_writers.rb +18 -16
- data/lib/rails/graphql/request/prepared_data.rb +98 -0
- data/lib/rails/graphql/request/steps/authorizable.rb +24 -14
- data/lib/rails/graphql/request/steps/organizable.rb +110 -48
- data/lib/rails/graphql/request/steps/{prepareable.rb → preparable.rb} +20 -7
- data/lib/rails/graphql/request/steps/{resolveable.rb → resolvable.rb} +15 -6
- data/lib/rails/graphql/request/strategy/cached_strategy.rb +64 -0
- data/lib/rails/graphql/request/strategy/dynamic_instance.rb +6 -6
- data/lib/rails/graphql/request/strategy/multi_query_strategy.rb +6 -13
- data/lib/rails/graphql/request/strategy/sequenced_strategy.rb +9 -9
- data/lib/rails/graphql/request/strategy.rb +131 -75
- data/lib/rails/graphql/request/subscription.rb +80 -0
- data/lib/rails/graphql/request.rb +305 -86
- data/lib/rails/graphql/schema.rb +240 -48
- data/lib/rails/graphql/shortcuts.rb +22 -3
- data/lib/rails/graphql/source/active_record/builders.rb +49 -35
- data/lib/rails/graphql/source/active_record_source.rb +70 -54
- data/lib/rails/graphql/source/base.rb +111 -0
- data/lib/rails/graphql/source/builder.rb +128 -0
- data/lib/rails/graphql/source/scoped_arguments.rb +31 -19
- data/lib/rails/graphql/source.rb +89 -213
- data/lib/rails/graphql/subscription/provider/action_cable.rb +112 -0
- data/lib/rails/graphql/subscription/provider/base.rb +191 -0
- data/lib/rails/graphql/subscription/provider.rb +18 -0
- data/lib/rails/graphql/subscription/store/base.rb +145 -0
- data/lib/rails/graphql/subscription/store/memory.rb +127 -0
- data/lib/rails/graphql/subscription/store.rb +19 -0
- data/lib/rails/graphql/subscription.rb +17 -0
- data/lib/rails/graphql/to_gql.rb +29 -32
- data/lib/rails/graphql/type/enum/directive_location_enum.rb +11 -11
- data/lib/rails/graphql/type/enum/type_kind_enum.rb +3 -3
- data/lib/rails/graphql/type/enum.rb +34 -48
- data/lib/rails/graphql/type/input.rb +74 -23
- data/lib/rails/graphql/type/interface.rb +16 -26
- data/lib/rails/graphql/type/object/directive_object.rb +4 -4
- data/lib/rails/graphql/type/object/enum_value_object.rb +3 -3
- data/lib/rails/graphql/type/object/field_object.rb +24 -6
- data/lib/rails/graphql/type/object/input_value_object.rb +3 -3
- data/lib/rails/graphql/type/object/schema_object.rb +5 -8
- data/lib/rails/graphql/type/object/type_object.rb +29 -19
- data/lib/rails/graphql/type/object.rb +26 -23
- data/lib/rails/graphql/type/scalar/any_scalar.rb +30 -0
- data/lib/rails/graphql/type/scalar/bigint_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar/binary_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/boolean_scalar.rb +8 -8
- data/lib/rails/graphql/type/scalar/date_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/date_time_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/decimal_scalar.rb +3 -3
- data/lib/rails/graphql/type/scalar/float_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar/id_scalar.rb +6 -5
- data/lib/rails/graphql/type/scalar/int_scalar.rb +6 -5
- data/lib/rails/graphql/type/scalar/json_scalar.rb +39 -0
- data/lib/rails/graphql/type/scalar/string_scalar.rb +18 -4
- data/lib/rails/graphql/type/scalar/time_scalar.rb +5 -5
- data/lib/rails/graphql/type/scalar.rb +25 -22
- data/lib/rails/graphql/type/union.rb +14 -16
- data/lib/rails/graphql/type.rb +34 -25
- data/lib/rails/graphql/type_map.rb +256 -164
- data/lib/rails/graphql/uri.rb +166 -0
- data/lib/rails/graphql/version.rb +15 -3
- data/lib/rails/graphql.rake +3 -0
- data/lib/rails/graphql.rb +85 -52
- data/lib/rails-graphql.rb +1 -1
- data/test/assets/en.yml +29 -0
- data/test/assets/introspection-mem.txt +1 -1
- data/test/assets/mem.gql +18 -45
- data/test/assets/mysql.gql +392 -0
- data/test/assets/sqlite.gql +21 -12
- data/test/assets/translate.gql +335 -0
- data/test/config.rb +18 -8
- data/test/graphql/schema_test.rb +12 -19
- data/test/graphql/source_test.rb +8 -75
- data/test/graphql/type/enum_test.rb +207 -203
- data/test/graphql/type/input_test.rb +14 -9
- data/test/graphql/type/interface_test.rb +4 -4
- data/test/graphql/type/scalar/any_scalar_test.rb +38 -0
- data/test/graphql/type/scalar/boolean_scalar_test.rb +6 -3
- data/test/graphql/type/scalar/json_scalar_test.rb +23 -0
- data/test/graphql/type_map_test.rb +51 -66
- data/test/graphql/type_test.rb +0 -19
- data/test/graphql_test.rb +1 -1
- data/test/integration/{authorization/authorization_test.rb → authorization_test.rb} +40 -14
- data/test/integration/config.rb +36 -3
- data/test/integration/customization_test.rb +39 -0
- data/test/integration/global_id_test.rb +99 -0
- data/test/integration/memory/star_wars_introspection_test.rb +24 -16
- data/test/integration/memory/star_wars_query_test.rb +54 -3
- data/test/integration/memory/star_wars_validation_test.rb +1 -1
- data/test/integration/mysql/star_wars_introspection_test.rb +25 -0
- data/test/integration/persisted_query_test.rb +87 -0
- data/test/integration/resolver_precedence_test.rb +154 -0
- data/test/integration/schemas/memory.rb +22 -7
- data/test/integration/schemas/mysql.rb +62 -0
- data/test/integration/schemas/sqlite.rb +21 -12
- data/test/integration/sqlite/star_wars_global_id_test.rb +83 -0
- data/test/integration/sqlite/star_wars_introspection_test.rb +10 -0
- data/test/integration/sqlite/star_wars_query_test.rb +14 -1
- data/test/integration/translate_test.rb +61 -0
- data/test/test_ext.rb +16 -13
- metadata +108 -157
- data/ext/depend +0 -3
- data/ext/graphqlparser/Ast.cpp +0 -346
- data/ext/graphqlparser/Ast.h +0 -1214
- data/ext/graphqlparser/AstNode.h +0 -36
- data/ext/graphqlparser/AstVisitor.h +0 -137
- data/ext/graphqlparser/GraphQLParser.cpp +0 -76
- data/ext/graphqlparser/GraphQLParser.h +0 -55
- data/ext/graphqlparser/JsonVisitor.cpp +0 -161
- data/ext/graphqlparser/JsonVisitor.cpp.inc +0 -456
- data/ext/graphqlparser/JsonVisitor.h +0 -121
- data/ext/graphqlparser/JsonVisitor.h.inc +0 -110
- data/ext/graphqlparser/VERSION +0 -1
- data/ext/graphqlparser/c/GraphQLAst.cpp +0 -324
- data/ext/graphqlparser/c/GraphQLAst.h +0 -180
- data/ext/graphqlparser/c/GraphQLAstForEachConcreteType.h +0 -44
- data/ext/graphqlparser/c/GraphQLAstNode.cpp +0 -25
- data/ext/graphqlparser/c/GraphQLAstNode.h +0 -33
- data/ext/graphqlparser/c/GraphQLAstToJSON.cpp +0 -21
- data/ext/graphqlparser/c/GraphQLAstToJSON.h +0 -24
- data/ext/graphqlparser/c/GraphQLAstVisitor.cpp +0 -55
- data/ext/graphqlparser/c/GraphQLAstVisitor.h +0 -53
- data/ext/graphqlparser/c/GraphQLParser.cpp +0 -35
- data/ext/graphqlparser/c/GraphQLParser.h +0 -54
- data/ext/graphqlparser/dump_json_ast.cpp +0 -48
- data/ext/graphqlparser/lexer.lpp +0 -324
- data/ext/graphqlparser/parser.ypp +0 -693
- data/ext/graphqlparser/parsergen/lexer.cpp +0 -2633
- data/ext/graphqlparser/parsergen/lexer.h +0 -528
- data/ext/graphqlparser/parsergen/location.hh +0 -189
- data/ext/graphqlparser/parsergen/parser.tab.cpp +0 -3300
- data/ext/graphqlparser/parsergen/parser.tab.hpp +0 -646
- data/ext/graphqlparser/parsergen/position.hh +0 -179
- data/ext/graphqlparser/parsergen/stack.hh +0 -156
- data/ext/graphqlparser/syntaxdefs.h +0 -19
- data/ext/libgraphqlparser/AstNode.h +0 -36
- data/ext/libgraphqlparser/CMakeLists.txt +0 -148
- data/ext/libgraphqlparser/CONTRIBUTING.md +0 -23
- data/ext/libgraphqlparser/GraphQLParser.cpp +0 -76
- data/ext/libgraphqlparser/GraphQLParser.h +0 -55
- data/ext/libgraphqlparser/JsonVisitor.cpp +0 -161
- data/ext/libgraphqlparser/JsonVisitor.h +0 -121
- data/ext/libgraphqlparser/LICENSE +0 -22
- data/ext/libgraphqlparser/README.clang-tidy +0 -7
- data/ext/libgraphqlparser/README.md +0 -84
- data/ext/libgraphqlparser/ast/ast.ast +0 -203
- data/ext/libgraphqlparser/ast/ast.py +0 -61
- data/ext/libgraphqlparser/ast/c.py +0 -100
- data/ext/libgraphqlparser/ast/c.pyc +0 -0
- data/ext/libgraphqlparser/ast/c_impl.py +0 -61
- data/ext/libgraphqlparser/ast/c_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/c_visitor_impl.py +0 -39
- data/ext/libgraphqlparser/ast/c_visitor_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/casing.py +0 -26
- data/ext/libgraphqlparser/ast/casing.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx.py +0 -197
- data/ext/libgraphqlparser/ast/cxx.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_impl.py +0 -61
- data/ext/libgraphqlparser/ast/cxx_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_json_visitor_header.py +0 -42
- data/ext/libgraphqlparser/ast/cxx_json_visitor_header.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.py +0 -80
- data/ext/libgraphqlparser/ast/cxx_json_visitor_impl.pyc +0 -0
- data/ext/libgraphqlparser/ast/cxx_visitor.py +0 -64
- data/ext/libgraphqlparser/ast/cxx_visitor.pyc +0 -0
- data/ext/libgraphqlparser/ast/js.py +0 -65
- data/ext/libgraphqlparser/ast/license.py +0 -10
- data/ext/libgraphqlparser/ast/license.pyc +0 -0
- data/ext/libgraphqlparser/c/GraphQLAstNode.cpp +0 -25
- data/ext/libgraphqlparser/c/GraphQLAstNode.h +0 -33
- data/ext/libgraphqlparser/c/GraphQLAstToJSON.cpp +0 -21
- data/ext/libgraphqlparser/c/GraphQLAstToJSON.h +0 -24
- data/ext/libgraphqlparser/c/GraphQLAstVisitor.cpp +0 -55
- data/ext/libgraphqlparser/c/GraphQLAstVisitor.h +0 -53
- data/ext/libgraphqlparser/c/GraphQLParser.cpp +0 -35
- data/ext/libgraphqlparser/c/GraphQLParser.h +0 -54
- data/ext/libgraphqlparser/clang-tidy-all.sh +0 -3
- data/ext/libgraphqlparser/cmake/version.cmake +0 -16
- data/ext/libgraphqlparser/dump_json_ast.cpp +0 -48
- data/ext/libgraphqlparser/go/README.md +0 -20
- data/ext/libgraphqlparser/go/callbacks.go +0 -18
- data/ext/libgraphqlparser/go/gotest.go +0 -64
- data/ext/libgraphqlparser/lexer.lpp +0 -324
- data/ext/libgraphqlparser/libgraphqlparser.pc.in +0 -11
- data/ext/libgraphqlparser/parser.ypp +0 -693
- data/ext/libgraphqlparser/parsergen/lexer.cpp +0 -2633
- data/ext/libgraphqlparser/parsergen/lexer.h +0 -528
- data/ext/libgraphqlparser/parsergen/location.hh +0 -189
- data/ext/libgraphqlparser/parsergen/parser.tab.cpp +0 -3300
- data/ext/libgraphqlparser/parsergen/parser.tab.hpp +0 -646
- data/ext/libgraphqlparser/parsergen/position.hh +0 -179
- data/ext/libgraphqlparser/parsergen/stack.hh +0 -156
- data/ext/libgraphqlparser/python/CMakeLists.txt +0 -14
- data/ext/libgraphqlparser/python/README.md +0 -5
- data/ext/libgraphqlparser/python/example.py +0 -31
- data/ext/libgraphqlparser/syntaxdefs.h +0 -19
- data/ext/libgraphqlparser/test/BuildCAPI.c +0 -5
- data/ext/libgraphqlparser/test/CMakeLists.txt +0 -25
- data/ext/libgraphqlparser/test/JsonVisitorTests.cpp +0 -28
- data/ext/libgraphqlparser/test/ParserTests.cpp +0 -352
- data/ext/libgraphqlparser/test/kitchen-sink.graphql +0 -59
- data/ext/libgraphqlparser/test/kitchen-sink.json +0 -1
- data/ext/libgraphqlparser/test/schema-kitchen-sink.graphql +0 -78
- data/ext/libgraphqlparser/test/schema-kitchen-sink.json +0 -1
- data/ext/libgraphqlparser/test/valgrind.supp +0 -33
- data/ext/version.cpp +0 -21
- data/lib/graphqlparser.so +0 -0
- data/lib/rails/graphql/native/functions.rb +0 -38
- data/lib/rails/graphql/native/location.rb +0 -41
- data/lib/rails/graphql/native/pointers.rb +0 -23
- data/lib/rails/graphql/native/visitor.rb +0 -349
- data/lib/rails/graphql/native.rb +0 -56
- data/test/integration/schemas/authorization.rb +0 -12
@@ -86,6 +86,21 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
86
86
|
GQL
|
87
87
|
end
|
88
88
|
|
89
|
+
def test_using_alias_to_change_key_name_on_array
|
90
|
+
friends = [
|
91
|
+
{ name: 'Han Solo' },
|
92
|
+
{ name: 'Leia Organa' },
|
93
|
+
{ name: 'C-3PO' },
|
94
|
+
{ name: 'R2-D2' },
|
95
|
+
]
|
96
|
+
|
97
|
+
assert_result({ data: { luke: { name: 'Luke Skywalker', others: friends } } }, <<~GQL)
|
98
|
+
query FetchLukeDeepAliased { luke: human(id: "1000") {
|
99
|
+
name others: friends { name }
|
100
|
+
} }
|
101
|
+
GQL
|
102
|
+
end
|
103
|
+
|
89
104
|
def test_using_alias_to_change_key_name_twice
|
90
105
|
luke = { name: 'Luke Skywalker' }
|
91
106
|
leia = { name: 'Leia Organa' }
|
@@ -108,6 +123,15 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
108
123
|
GQL
|
109
124
|
end
|
110
125
|
|
126
|
+
def test_query_with_field_argument
|
127
|
+
vader = { name: 'Darth Vader', greeting: 'Be gone Luke!' }
|
128
|
+
assert_result({ data: { human: vader } }, <<~GQL, variables: { name: 'Luke' })
|
129
|
+
query WithFieldArgument($name: String!) {
|
130
|
+
human(id: "1001") { name greeting(name: $name) }
|
131
|
+
}
|
132
|
+
GQL
|
133
|
+
end
|
134
|
+
|
111
135
|
def test_query_with_fragment
|
112
136
|
luke = { name: 'Luke Skywalker', homePlanet: 'Tatooine' }
|
113
137
|
leia = { name: 'Leia Organa', homePlanet: 'Alderaan' }
|
@@ -124,6 +148,33 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
124
148
|
GQL
|
125
149
|
end
|
126
150
|
|
151
|
+
def test_query_with_fragment_and_field_argument
|
152
|
+
vader = { name: 'Darth Vader', greeting: 'Be gone Luke!' }
|
153
|
+
assert_result({ data: { human: vader } }, <<~GQL, variables: { name: 'Luke' })
|
154
|
+
query WithFieldArgument($name: String!) {
|
155
|
+
human(id: "1001") { ...HumanFragment }
|
156
|
+
}
|
157
|
+
|
158
|
+
fragment HumanFragment on Human { name greeting(name: $name) }
|
159
|
+
GQL
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_query_with_fragment_and_field_argument_and_default_values
|
163
|
+
first = { human: { name: 'Darth Vader', greeting: 'Be gone Luke!' } }
|
164
|
+
second = { human: { name: 'Darth Vader', greeting: 'Be gone Leia!' } }
|
165
|
+
assert_result({ data: { first: first, second: second } }, <<~GQL)
|
166
|
+
query first($id: ID! = 1001, $name: String! = "Luke") {
|
167
|
+
human(id: $id) { ...HumanFragment }
|
168
|
+
}
|
169
|
+
|
170
|
+
query second($id: ID! = 1001, $name: String! = "Leia") {
|
171
|
+
human(id: $id) { ...HumanFragment }
|
172
|
+
}
|
173
|
+
|
174
|
+
fragment HumanFragment on Human { name greeting(name: $name) }
|
175
|
+
GQL
|
176
|
+
end
|
177
|
+
|
127
178
|
def test_get_typename_field
|
128
179
|
assert_result({ data: { hero: { __typename: 'Droid', name: 'R2-D2' } } }, <<~GQL)
|
129
180
|
query CheckTypeOfR2 { hero { __typename name } }
|
@@ -143,7 +194,7 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
143
194
|
message: 'Secret backstory is secret',
|
144
195
|
locations: [{ line: 1, column: 35 }, { line: 1, column: 50 }],
|
145
196
|
path: %w[HeroNameQuery hero secretBackstory],
|
146
|
-
extensions: { exception: 'RuntimeError' },
|
197
|
+
extensions: { stage: 'resolve', exception: 'RuntimeError' },
|
147
198
|
}]
|
148
199
|
|
149
200
|
assert_result({ data: { hero: hero }, errors: errors }, <<~GQL)
|
@@ -159,7 +210,7 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
159
210
|
message: 'Secret backstory is secret',
|
160
211
|
locations: [{ line: 1, column: 50 }, { line: 1, column: 65 }],
|
161
212
|
path: ['HeroNameQuery', 'hero', 'friends', n, 'secretBackstory'],
|
162
|
-
extensions: { exception: 'RuntimeError' },
|
213
|
+
extensions: { stage: 'resolve', exception: 'RuntimeError' },
|
163
214
|
}
|
164
215
|
end
|
165
216
|
|
@@ -174,7 +225,7 @@ class Integration_Memory_StarWarsQueryTest < GraphQL::IntegrationTestCase
|
|
174
225
|
message: 'Secret backstory is secret',
|
175
226
|
locations: [{ line: 1, column: 35 }, { line: 1, column: 57 }],
|
176
227
|
path: %w[HeroNameQuery hero story],
|
177
|
-
extensions: { exception: 'RuntimeError' },
|
228
|
+
extensions: { stage: 'resolve', exception: 'RuntimeError' },
|
178
229
|
}]
|
179
230
|
|
180
231
|
assert_result({ data: { hero: hero }, errors: errors }, <<~GQL)
|
@@ -23,7 +23,7 @@ class Integration_Memory_StarWarsValidationTest < GraphQL::IntegrationTestCase
|
|
23
23
|
|
24
24
|
def test_invalid_query
|
25
25
|
errors = [{
|
26
|
-
message: '
|
26
|
+
message: 'Parser error: unexpected "EOF"',
|
27
27
|
locations: [{ line: 2, column: 1 }],
|
28
28
|
}]
|
29
29
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'integration/config'
|
2
|
+
|
3
|
+
class Integration_MySQL_StarWarsIntrospectionTest < GraphQL::IntegrationTestCase
|
4
|
+
load_schema 'mysql'
|
5
|
+
|
6
|
+
SCHEMA = ::StartWarsMySQLSchema
|
7
|
+
|
8
|
+
def test_auto_introspection
|
9
|
+
assert(SCHEMA.introspection?)
|
10
|
+
assert(SCHEMA.has_field?(:query, :__schema))
|
11
|
+
assert(SCHEMA.has_field?(:query, :__type))
|
12
|
+
end
|
13
|
+
|
14
|
+
# Test this spec with all avaliable scalars
|
15
|
+
def remove_keys_form_type_map
|
16
|
+
end
|
17
|
+
|
18
|
+
# There are some issues with the end sorting, so compare the string result
|
19
|
+
# with sorted characters, which will produce the exact match
|
20
|
+
def test_gql_introspection
|
21
|
+
# File.write('test/assets/mysql.gql', SCHEMA.to_gql)
|
22
|
+
result = gql_file('mysql').split('').sort.join.squish
|
23
|
+
assert_equal(result, SCHEMA.to_gql.split('').sort.join.squish)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'integration/config'
|
2
|
+
|
3
|
+
class Integration_PersistedQueryTest < GraphQL::IntegrationTestCase
|
4
|
+
class SCHEMA < GraphQL::Schema
|
5
|
+
namespace :cached
|
6
|
+
|
7
|
+
configure do |config|
|
8
|
+
config.enable_string_collector = false
|
9
|
+
config.default_response_format = :json
|
10
|
+
end
|
11
|
+
|
12
|
+
query_fields do
|
13
|
+
field(:one, :string).resolve { 'One!' }
|
14
|
+
field(:two, :string).resolve { 'Two!' }
|
15
|
+
end
|
16
|
+
|
17
|
+
class_attribute :cache, instance_writer: false, default: {}
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def cached?(name, *)
|
21
|
+
cache.key?(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_from_cache(name, *)
|
25
|
+
cache.delete(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_from_cache(name, *)
|
29
|
+
cache[name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_on_cache(name, value, *)
|
33
|
+
cache[name] = value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def teardown
|
39
|
+
SCHEMA.cache.clear
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_uncached_query
|
43
|
+
assert_result('One!', :one)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_cache_key
|
47
|
+
gen_key = cache_key('B')
|
48
|
+
assert_equal('graphql/cached/A', SCHEMA.send(:expand_cache_key, 'A'))
|
49
|
+
assert_equal('graphql/cached/B', SCHEMA.send(:expand_cache_key, gen_key).cache_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_cached_query
|
53
|
+
value = ::GQLParser.parse_execution('{ two }')
|
54
|
+
SCHEMA.write_on_cache((key = cache_key), value)
|
55
|
+
assert_result('Two!', :two, hash: key, cache_only: true)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_persist_query
|
59
|
+
assert_result('One!', :one, hash: (key = cache_key))
|
60
|
+
assert_operator(SCHEMA, :cached?, key)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_subsequent_query
|
64
|
+
assert_result('One!', :one, hash: (key = cache_key))
|
65
|
+
assert_result('One!', :one, hash: key, cache_only: true)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_execute_compiled_query
|
69
|
+
query = GraphQL.compile('{ one }', schema: SCHEMA)
|
70
|
+
result = GraphQL.execute(query, compiled: true, schema: SCHEMA)
|
71
|
+
|
72
|
+
assert_equal('One!', result.dig('data', 'one'))
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def cache_key(key = nil, version = nil)
|
78
|
+
key ||= SCHEMA.config.cache_prefix + SecureRandom.uuid
|
79
|
+
Rails::GraphQL::CacheKey.new(key, version)
|
80
|
+
end
|
81
|
+
|
82
|
+
def assert_result(value, field, **options)
|
83
|
+
query = options.delete(:cache_only) ? nil : "{ #{field} }"
|
84
|
+
result = GraphQL.execute(query, **options, schema: SCHEMA)
|
85
|
+
assert_equal(value, result.dig('data', field.to_s))
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'integration/config'
|
2
|
+
|
3
|
+
class Integration_ResolverPrecedenceTest < GraphQL::IntegrationTestCase
|
4
|
+
EVENT_HANDLERS = { resolve: :@resolver, perform: :@performer }
|
5
|
+
|
6
|
+
class SCHEMA < GraphQL::Schema
|
7
|
+
namespace :precedence
|
8
|
+
|
9
|
+
configure do |config|
|
10
|
+
config.enable_string_collector = false
|
11
|
+
config.default_response_format = :json
|
12
|
+
end
|
13
|
+
|
14
|
+
object 'Object1' do
|
15
|
+
field(:field1, :string)
|
16
|
+
end
|
17
|
+
|
18
|
+
query_fields do
|
19
|
+
field(:query1, :string)
|
20
|
+
field(:query2, 'Object1').resolve { OpenStruct.new(field1: 'Default Value') }
|
21
|
+
end
|
22
|
+
|
23
|
+
mutation_fields do
|
24
|
+
field(:mutation1, :string).perform { }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :object, :field
|
29
|
+
|
30
|
+
def test_simple_query
|
31
|
+
object = SCHEMA
|
32
|
+
field = object[:query][:query1]
|
33
|
+
|
34
|
+
# (1) Resolver as block comes first
|
35
|
+
stub_handler(field, :resolve, -> { 'Ok 1' }) do
|
36
|
+
assert_result('Ok 1', 'query1')
|
37
|
+
end
|
38
|
+
|
39
|
+
# (2) Method on schema comes second
|
40
|
+
stub_callable(object, field, :query1, -> { 'Ok 2' }) do
|
41
|
+
assert_result('Ok 2', 'query1')
|
42
|
+
end
|
43
|
+
|
44
|
+
# (1) Resolver block has higher precedence than method on schema
|
45
|
+
stub_callable(object, field, :query1, -> { 'Nok 3' }) do
|
46
|
+
stub_handler(field, :resolve, -> { 'Ok 3' }) do
|
47
|
+
assert_result('Ok 3', 'query1')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_simple_mutation
|
53
|
+
object = SCHEMA
|
54
|
+
field = object[:mutation][:mutation1]
|
55
|
+
|
56
|
+
# (1) With performer but no resolver has the higher precedence
|
57
|
+
$check = true
|
58
|
+
stub_handler(field, :perform, -> { 'Ok 1' }) do
|
59
|
+
assert_result('Ok 1', 'mutation1', :mutation)
|
60
|
+
end
|
61
|
+
|
62
|
+
# (2) Performer first and then resolver has the second precedence
|
63
|
+
result = ''
|
64
|
+
stub_handler(field, :perform, -> { result << 'Ok 2' }) do
|
65
|
+
stub_handler(field, :resolve, -> { result << 'Ok 3' }) do
|
66
|
+
assert_result('Ok 2Ok 3', 'mutation1', :mutation)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# (3) Performer as a method but resolver as block
|
71
|
+
result = ''
|
72
|
+
stub_callable(object, field, :mutation1!, -> { result << 'Ok 4' }) do
|
73
|
+
stub_handler(field, :resolve, -> { result << 'Ok 5' }) do
|
74
|
+
assert_result('Ok 4Ok 5', 'mutation1', :mutation)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# (4) Performer as a method first and then resolve as a method
|
79
|
+
result = ''
|
80
|
+
stub_callable(object, field, :mutation1!, -> { result << 'Ok 6' }) do
|
81
|
+
stub_callable(object, field, :mutation1, -> { result << 'Ok 7' }) do
|
82
|
+
assert_result('Ok 6Ok 7', 'mutation1', :mutation)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# (2) Blocks has higher precedence than methods
|
87
|
+
result = ''
|
88
|
+
stub_callable(object, field, :mutation1!, -> { result << 'Nok 8' }) do
|
89
|
+
stub_callable(object, field, :mutation1, -> { result << 'Nok 9' }) do
|
90
|
+
stub_handler(field, :perform, -> { result << 'Ok 8' }) do
|
91
|
+
stub_handler(field, :resolve, -> { result << 'Ok 9' }) do
|
92
|
+
assert_result('Ok 8Ok 9', 'mutation1', :mutation)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_simple_object
|
100
|
+
object = GraphQL::Object1Object
|
101
|
+
field = object[:field1]
|
102
|
+
|
103
|
+
# (1) Block has higher precedence than default value
|
104
|
+
stub_handler(field, :resolve, -> { 'Ok 1' }) do
|
105
|
+
assert_result('Ok 1', 'field1.query2')
|
106
|
+
end
|
107
|
+
|
108
|
+
# (2) Method on object comes second
|
109
|
+
stub_callable(object, field, :field1, -> { 'Ok 2' }) do
|
110
|
+
assert_result('Ok 2', 'field1.query2')
|
111
|
+
end
|
112
|
+
|
113
|
+
# (3) Lastly it will simply put the original resolved value
|
114
|
+
assert_result('Default Value', 'field1.query2')
|
115
|
+
|
116
|
+
# (1) Block has higher precedence than methond on object
|
117
|
+
stub_callable(object, field, :field1, -> { 'Nok 3' }) do
|
118
|
+
stub_handler(field, :resolve, -> { 'Ok 3' }) do
|
119
|
+
assert_result('Ok 3', 'field1.query2')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
protected
|
125
|
+
|
126
|
+
def assert_result(expected, field, operation = :query)
|
127
|
+
doc, data = field.split('.').reduce(['', expected]) do |(d, r), part|
|
128
|
+
["{ #{part} #{d} }", { part => r }]
|
129
|
+
end
|
130
|
+
|
131
|
+
super({ data: data }, "#{operation} #{doc}")
|
132
|
+
end
|
133
|
+
|
134
|
+
def stub_handler(field, event, *args, **xargs)
|
135
|
+
block = args.shift if args.first.is_a?(Proc)
|
136
|
+
cb = create_callback(field, event, *args, **xargs, &block)
|
137
|
+
|
138
|
+
field.get_reset_ivar(:@dynamic_resolver, event == :resolve) do
|
139
|
+
field.stub_ivar(EVENT_HANDLERS[event], cb) { yield }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def stub_callable(object, field, method_name, block)
|
144
|
+
field.get_reset_ivar(:@dynamic_resolver) do
|
145
|
+
field.get_reset_ivar(:@resolver) do
|
146
|
+
object.stub_imethod(method_name, block) { yield }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def create_callback(source, event, *args, **xargs, &block)
|
152
|
+
Rails::GraphQL::Callback.new(source, event, *args, **xargs, &block)
|
153
|
+
end
|
154
|
+
end
|
@@ -25,7 +25,7 @@ module MemoryTest
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class Human < Character
|
28
|
-
attr_accessor :home_planet
|
28
|
+
attr_accessor :home_planet, :greeting
|
29
29
|
end
|
30
30
|
|
31
31
|
class Droid < Character
|
@@ -39,33 +39,38 @@ module MemoryTest
|
|
39
39
|
name: 'Luke Skywalker',
|
40
40
|
friends: ['1002', '1003', '2000', '2001'],
|
41
41
|
appears_in: [0, 1, 2],
|
42
|
-
home_planet: 'Tatooine'
|
42
|
+
home_planet: 'Tatooine',
|
43
|
+
greeting: 'Hi %s!',
|
43
44
|
),
|
44
45
|
'1001' => Human.new(
|
45
46
|
id: '1001',
|
46
47
|
name: 'Darth Vader',
|
47
48
|
friends: ['1004'],
|
48
49
|
appears_in: [0, 1, 2],
|
49
|
-
home_planet: 'Tatooine'
|
50
|
+
home_planet: 'Tatooine',
|
51
|
+
greeting: 'Be gone %s!',
|
50
52
|
),
|
51
53
|
'1002' => Human.new(
|
52
54
|
id: '1002',
|
53
55
|
name: 'Han Solo',
|
54
56
|
friends: ['1000', '1003', '2001'],
|
55
|
-
appears_in: [0, 1, 2]
|
57
|
+
appears_in: [0, 1, 2],
|
58
|
+
greeting: 'Hello %s!',
|
56
59
|
),
|
57
60
|
'1003' => Human.new(
|
58
61
|
id: '1003',
|
59
62
|
name: 'Leia Organa',
|
60
63
|
friends: ['1000', '1002', '2000', '2001'],
|
61
64
|
appears_in: [0, 1, 2],
|
62
|
-
home_planet: 'Alderaan'
|
65
|
+
home_planet: 'Alderaan',
|
66
|
+
greeting: 'Greetings %s!',
|
63
67
|
),
|
64
68
|
'1004' => Human.new(
|
65
69
|
id: '1004',
|
66
70
|
name: 'Wilhuff Tarkin',
|
67
71
|
friends: ['1001'],
|
68
|
-
appears_in: [0]
|
72
|
+
appears_in: [0],
|
73
|
+
greeting: 'Sup %s!',
|
69
74
|
),
|
70
75
|
},
|
71
76
|
droids: {
|
@@ -92,10 +97,12 @@ class StartWarsMemSchema < GraphQL::Schema
|
|
92
97
|
|
93
98
|
configure do |config|
|
94
99
|
config.enable_string_collector = false
|
100
|
+
config.default_response_format = :json
|
95
101
|
end
|
96
102
|
|
97
103
|
rescue_from('StandardError') do |exception|
|
98
|
-
|
104
|
+
raise unless exception.source.is_a?(Rails::GraphQL::Request::Component::Field)
|
105
|
+
exception.request.exception_to_error(exception, exception.source)
|
99
106
|
end
|
100
107
|
|
101
108
|
enum 'Episode' do
|
@@ -149,6 +156,14 @@ class StartWarsMemSchema < GraphQL::Schema
|
|
149
156
|
|
150
157
|
field :home_planet, :string,
|
151
158
|
desc: 'The home planet of the human, or null if unknown'
|
159
|
+
|
160
|
+
field :greeting, :string,
|
161
|
+
desc: 'A greeting phrase from this person to someone',
|
162
|
+
arguments: arg(:name, :string, null: false)
|
163
|
+
|
164
|
+
def greeting(name:)
|
165
|
+
format(current_value.greeting, name)
|
166
|
+
end
|
152
167
|
end
|
153
168
|
|
154
169
|
object 'Droid' do
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class MySQLRecord < ActiveRecord::Base
|
4
|
+
self.abstract_class = true
|
5
|
+
|
6
|
+
establish_connection(
|
7
|
+
name: 'mysql',
|
8
|
+
adapter: 'mysql2',
|
9
|
+
host: ENV.fetch('GQL_MYSQL_HOST', 'localhost'),
|
10
|
+
database: ENV.fetch('GQL_MYSQL_DATABASE', 'starwars'),
|
11
|
+
username: ENV.fetch('GQL_MYSQL_USERNAME', 'root'),
|
12
|
+
password: ENV['GQL_MYSQL_PASSWORD'],
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
MySQLRecord.connection.instance_eval do
|
17
|
+
create_table 'jedi_types', force: :cascade do |t|
|
18
|
+
t.string 'name'
|
19
|
+
end
|
20
|
+
|
21
|
+
create_table 'jedis', force: :cascade do |t|
|
22
|
+
t.integer 'jedi_type_id'
|
23
|
+
t.string 'name'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class JediType < MySQLRecord
|
28
|
+
has_many :jedi, class_name: 'Jedi', foreign_key: :jedi_type_id
|
29
|
+
|
30
|
+
accepts_nested_attributes_for :jedi
|
31
|
+
|
32
|
+
MASTER = create!(name: 'Master')
|
33
|
+
PADAWAN = create!(name: 'Padawan')
|
34
|
+
end
|
35
|
+
|
36
|
+
class Jedi < MySQLRecord
|
37
|
+
belongs_to :jedi_type, class_name: 'JediType', foreign_key: :jedi_type_id
|
38
|
+
|
39
|
+
validates :name, presence: true, if: -> { true }
|
40
|
+
|
41
|
+
create!(name: 'Ioda', jedi_type: JediType::MASTER)
|
42
|
+
create!(name: 'Obi-Wan Kenobi', jedi_type: JediType::MASTER)
|
43
|
+
create!(name: 'Anakin Skywalker', jedi_type: JediType::PADAWAN)
|
44
|
+
create!(name: 'Mace Windu', jedi_type: JediType::MASTER)
|
45
|
+
end
|
46
|
+
|
47
|
+
class StartWarsMySQLSchema < GraphQL::Schema
|
48
|
+
namespace :star_wars_mysql
|
49
|
+
|
50
|
+
configure do |config|
|
51
|
+
config.enable_string_collector = false
|
52
|
+
config.default_response_format = :json
|
53
|
+
end
|
54
|
+
|
55
|
+
source JediType do
|
56
|
+
with_options on: 'jediTypes' do
|
57
|
+
scoped_argument(:order) { |o| order(name: o) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
source Jedi
|
62
|
+
end
|
@@ -1,14 +1,17 @@
|
|
1
1
|
require 'active_record'
|
2
|
-
|
3
|
-
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
2
|
+
require 'active_record/database_configurations'
|
4
3
|
|
5
4
|
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
6
5
|
inflect.irregular 'base', 'bases'
|
7
6
|
end
|
8
7
|
|
9
|
-
ActiveRecord::
|
10
|
-
self.
|
8
|
+
class SQLiteRecord < ActiveRecord::Base
|
9
|
+
self.abstract_class = true
|
11
10
|
|
11
|
+
establish_connection(adapter: 'sqlite3', database: ':memory:')
|
12
|
+
end
|
13
|
+
|
14
|
+
SQLiteRecord.connection.instance_eval do
|
12
15
|
create_table 'lite_factions', force: :cascade do |t|
|
13
16
|
t.string 'name'
|
14
17
|
end
|
@@ -25,10 +28,6 @@ ActiveRecord::Schema.define(version: 1) do
|
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
|
-
class SQLiteRecord < ActiveRecord::Base
|
29
|
-
self.abstract_class = true
|
30
|
-
end
|
31
|
-
|
32
31
|
class LiteFaction < SQLiteRecord
|
33
32
|
has_many :bases, class_name: 'LiteBase', foreign_key: :faction_id
|
34
33
|
has_many :ships, class_name: 'LiteShip', foreign_key: :faction_id
|
@@ -43,6 +42,8 @@ end
|
|
43
42
|
class LiteBase < SQLiteRecord
|
44
43
|
belongs_to :faction, class_name: 'LiteFaction', foreign_key: :faction_id
|
45
44
|
|
45
|
+
validates :name, presence: true
|
46
|
+
|
46
47
|
create!(name: 'Yavin', planet: 'Yavin 4', faction: LiteFaction::REBELS)
|
47
48
|
create!(name: 'Echo Base', planet: 'Hoth', faction: LiteFaction::REBELS)
|
48
49
|
create!(name: 'Secret Hideout', planet: 'Dantooine', faction: LiteFaction::REBELS)
|
@@ -54,6 +55,8 @@ end
|
|
54
55
|
class LiteShip < SQLiteRecord
|
55
56
|
belongs_to :faction, class_name: 'LiteFaction', foreign_key: :faction_id
|
56
57
|
|
58
|
+
validates :name, presence: true, if: -> { true }
|
59
|
+
|
57
60
|
create!(name: 'X-Wing', faction: LiteFaction::REBELS)
|
58
61
|
create!(name: 'Y-Wing', faction: LiteFaction::REBELS)
|
59
62
|
create!(name: 'A-Wing', faction: LiteFaction::REBELS)
|
@@ -65,18 +68,24 @@ class LiteShip < SQLiteRecord
|
|
65
68
|
end
|
66
69
|
|
67
70
|
class StartWarsSqliteSchema < GraphQL::Schema
|
68
|
-
namespace :
|
71
|
+
namespace :star_wars_sqlite
|
69
72
|
|
70
73
|
configure do |config|
|
71
74
|
config.enable_string_collector = false
|
75
|
+
config.default_response_format = :json
|
72
76
|
end
|
73
77
|
|
74
|
-
|
78
|
+
source LiteFaction do
|
75
79
|
with_options on: 'liteFactions' do
|
76
80
|
scoped_argument(:order) { |o| order(name: o) }
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
80
|
-
|
81
|
-
|
84
|
+
source LiteBase do
|
85
|
+
with_options on: 'liteBases' do
|
86
|
+
scoped_argument(:order, default: :desc) { |o| order(name: o) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
source LiteShip
|
82
91
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'integration/config'
|
2
|
+
|
3
|
+
class Integration_SQLite_StarWarsGlobalIDTest < GraphQL::IntegrationTestCase
|
4
|
+
load_schema 'sqlite'
|
5
|
+
|
6
|
+
SCHEMA = ::StartWarsSqliteSchema
|
7
|
+
|
8
|
+
## CREATE
|
9
|
+
|
10
|
+
def test_create_query_field
|
11
|
+
obj = GraphQL::LiteFactionSource[:query][:lite_factions]
|
12
|
+
assert_gid_value('gql://star-wars-sqlite/LiteFactionSource/query/liteFactions', obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_create_object
|
16
|
+
obj = GraphQL::LiteFactionSource.object
|
17
|
+
assert_gid_value('gql://star-wars-sqlite/Type/LiteFaction', obj)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_create_input
|
21
|
+
obj = GraphQL::LiteFactionSource.input
|
22
|
+
assert_gid_value('gql://star-wars-sqlite/Type/LiteFactionInput', obj)
|
23
|
+
|
24
|
+
obj = GraphQL::LiteFactionSource.input.deserialize(nil)
|
25
|
+
assert_gid_value('gql://star-wars-sqlite/Type/LiteFactionInput?', obj)
|
26
|
+
|
27
|
+
params = { name: 'Sample' }
|
28
|
+
obj = GraphQL::LiteFactionSource.input.deserialize(params)
|
29
|
+
assert_gid_value('gql://star-wars-sqlite/Type/LiteFactionInput?name=Sample', obj)
|
30
|
+
|
31
|
+
params = { name: 'Sample', bases_attributes: [{ name: 'Other' }] }
|
32
|
+
obj = GraphQL::LiteFactionSource.input.deserialize(params)
|
33
|
+
assert_gid_value('gql://star-wars-sqlite/Type/LiteFactionInput?basesAttributes[][name]=Other&name=Sample', obj)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_create_object_field
|
37
|
+
obj = GraphQL::LiteFactionSource.object[:name]
|
38
|
+
assert_gid_value('gql://star-wars-sqlite/LiteFactionObject/name', obj)
|
39
|
+
end
|
40
|
+
|
41
|
+
def assert_gid_value(result, object)
|
42
|
+
assert_equal(result.gsub(/\[|\]/, { '[' => '%5B', ']' => '%5D' }), object.to_gid.to_s)
|
43
|
+
end
|
44
|
+
|
45
|
+
## PARSE
|
46
|
+
|
47
|
+
def test_parse_query_field
|
48
|
+
obj = find_gid('gql://star-wars-sqlite/LiteFactionSource/query/liteFactions')
|
49
|
+
assert_equal(GraphQL::LiteFactionSource[:query][:lite_factions], obj)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_parse_object
|
53
|
+
obj = find_gid('gql://star-wars-sqlite/Type/LiteFaction')
|
54
|
+
assert_equal(GraphQL::LiteFactionSource.object, obj)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_parse_input
|
58
|
+
obj = find_gid('gql://star-wars-sqlite/Type/LiteFactionInput')
|
59
|
+
assert_equal(GraphQL::LiteFactionSource.input, obj)
|
60
|
+
|
61
|
+
obj = find_gid('gql://star-wars-sqlite/Type/LiteFactionInput?')
|
62
|
+
assert_instance_of(GraphQL::LiteFactionSource.input, obj)
|
63
|
+
assert_empty(obj.params)
|
64
|
+
|
65
|
+
obj = find_gid('gql://star-wars-sqlite/Type/LiteFactionInput?name=Sample')
|
66
|
+
assert_instance_of(GraphQL::LiteFactionSource.input, obj)
|
67
|
+
assert_equal('Sample', obj.params[:name])
|
68
|
+
|
69
|
+
obj = find_gid('gql://star-wars-sqlite/Type/LiteFactionInput?bases_attributes[][name]=Other&name=Sample')
|
70
|
+
assert_instance_of(GraphQL::LiteFactionSource.input, obj)
|
71
|
+
assert_equal([{name: 'Other'}], obj.params[:bases_attributes])
|
72
|
+
assert_equal('Sample', obj.params[:name])
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_parse_object_field
|
76
|
+
obj = find_gid('gql://star-wars-sqlite/LiteFactionObject/name')
|
77
|
+
assert_equal(GraphQL::LiteFactionSource.object[:name], obj)
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_gid(gid)
|
81
|
+
GraphQL::GlobalID.find(gid)
|
82
|
+
end
|
83
|
+
end
|