graphql-extras 0.2.6 → 0.3.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/README.md +57 -27
- data/graphql-extras.gemspec +1 -1
- data/lib/graphql/extras.rb +2 -1
- data/lib/graphql/extras/association_loader.rb +24 -0
- data/lib/graphql/extras/preload.rb +23 -0
- data/lib/graphql/extras/test.rb +1 -0
- data/lib/graphql/extras/test/loader.rb +59 -0
- data/lib/graphql/extras/test/response.rb +37 -0
- data/lib/graphql/extras/test/schema.rb +53 -0
- data/lib/graphql/extras/version.rb +1 -1
- metadata +10 -6
- data/lib/graphql/extras/batch.rb +0 -47
- data/lib/graphql/extras/rspec.rb +0 -133
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29213c20e07ca49b31f25ee4c66a1b60537c746ac3a66030eee023eb33d35f65
|
4
|
+
data.tar.gz: 45694df9fb4e00159e7394bcab9f9253de8dd949b891cc6b78a6e28fa548a99e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22ca80f894bdae011ee6707f35a43097b699534dfc4295e5369100f993dced3a6906df29518dff0729683320db7dd72d9186c0edc8d0378ffb2b5bee24941e0d
|
7
|
+
data.tar.gz: e6df88738196ecf8b02b15fcad0da085ee6cfca9762a27dc06942458797b73a624fa300252338e3f04c92aff73a52a59543eeee29bc5f9ee2631c27563223423
|
data/README.md
CHANGED
@@ -2,13 +2,29 @@
|
|
2
2
|
|
3
3
|
<div align="center">
|
4
4
|
|
5
|
-

|
6
6
|

|
7
7
|
|
8
8
|
</div>
|
9
9
|
|
10
10
|
A collection of utilities for building GraphQL APIs.
|
11
11
|
|
12
|
+
**Table of Contents**
|
13
|
+
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Usage](#usage)
|
16
|
+
- [GraphQL::Extras::Controller](#graphqlextrascontroller)
|
17
|
+
- [GraphQL::Extras::AssociationLoader](#graphqlextrasassociationloader)
|
18
|
+
- [GraphQL::Extras::Preload](#graphqlextraspreload)
|
19
|
+
- [GraphQL::Extras::Types](#graphqlextrastypes)
|
20
|
+
- [Date](#date)
|
21
|
+
- [DateTime](#datetime)
|
22
|
+
- [Decimal](#decimal)
|
23
|
+
- [Upload](#upload)
|
24
|
+
- [GraphQL::Extras::Test](#graphqlextrastest)
|
25
|
+
- [Development](#development)
|
26
|
+
- [Contributing](#contributing)
|
27
|
+
|
12
28
|
## Installation
|
13
29
|
|
14
30
|
Add this line to your application's Gemfile:
|
@@ -37,30 +53,36 @@ class GraphqlController < ApplicationController
|
|
37
53
|
end
|
38
54
|
```
|
39
55
|
|
40
|
-
### GraphQL::Extras::
|
56
|
+
### GraphQL::Extras::AssociationLoader
|
41
57
|
|
42
58
|
This is a subclass of [`GraphQL::Batch::Loader`](https://github.com/Shopify/graphql-batch) that performs eager loading of Active Record associations.
|
43
59
|
|
44
60
|
```ruby
|
45
|
-
loader = GraphQL::Extras::
|
61
|
+
loader = GraphQL::Extras::AssociationLoader.for(:blog)
|
46
62
|
loader.load(Post.first)
|
47
63
|
loader.load_many(Post.all)
|
48
64
|
```
|
49
65
|
|
50
|
-
### GraphQL::Extras::
|
66
|
+
### GraphQL::Extras::Preload
|
51
67
|
|
52
|
-
This
|
68
|
+
This allows you to preload associations before resolving fields.
|
53
69
|
|
54
70
|
```ruby
|
55
|
-
class
|
56
|
-
|
71
|
+
class BaseField < GraphQL::Schema::Field
|
72
|
+
prepend GraphQL::Extras::Preload
|
73
|
+
end
|
57
74
|
|
58
|
-
|
59
|
-
|
60
|
-
|
75
|
+
class BaseObject < GraphQL::Schema::Object
|
76
|
+
field_class BaseField
|
77
|
+
end
|
61
78
|
|
62
|
-
|
63
|
-
|
79
|
+
class PostType < BaseObject
|
80
|
+
field :author, AuthorType, preload: :author, null: false
|
81
|
+
field :author_posts, [PostType], preload: {author: :posts}, null: false
|
82
|
+
field :depends_on_author, Integer, preload: :author, null: false
|
83
|
+
|
84
|
+
def author_posts
|
85
|
+
object.author.posts
|
64
86
|
end
|
65
87
|
end
|
66
88
|
```
|
@@ -95,7 +117,7 @@ This scalar takes a `DateTime` and transmits it as a string, using ISO 8601 form
|
|
95
117
|
field :created_at, DateTime, required: true
|
96
118
|
```
|
97
119
|
|
98
|
-
|
120
|
+
_Note: This is just an alias for the `ISO8601DateTime` type that is included in the `graphql` gem._
|
99
121
|
|
100
122
|
#### Decimal
|
101
123
|
|
@@ -126,36 +148,44 @@ Take note of the correspondence between the value `"image"` and the additional H
|
|
126
148
|
|
127
149
|
See [apollo-link-upload](https://github.com/rzane/apollo-link-upload) for the client-side implementation.
|
128
150
|
|
129
|
-
###
|
151
|
+
### GraphQL::Extras::Test
|
152
|
+
|
153
|
+
This module makes it really easy to test your schema.
|
130
154
|
|
131
|
-
|
155
|
+
First, create a test schema:
|
132
156
|
|
133
157
|
```ruby
|
134
|
-
|
158
|
+
# spec/support/test_schema.rb
|
159
|
+
require "graphql/extras/test"
|
160
|
+
|
161
|
+
class TestSchema < GraphQL::Extras::Test::Schema
|
162
|
+
configure schema: Schema, queries: "spec/**/*.graphql"
|
163
|
+
end
|
135
164
|
```
|
136
165
|
|
137
166
|
Now, you can run tests like so:
|
138
167
|
|
139
168
|
```ruby
|
169
|
+
require "support/test_schema"
|
170
|
+
|
140
171
|
RSpec.describe "hello" do
|
141
172
|
let(:context) { { name: "Ray" } }
|
142
|
-
let(:schema) {
|
143
|
-
let(:queries) { graphql_fixture("hello.graphql") }
|
173
|
+
let(:schema) { TestSchema.new(context) }
|
144
174
|
|
145
175
|
it "allows easily executing queries" do
|
146
|
-
|
176
|
+
query = schema.hello
|
147
177
|
|
148
|
-
expect(
|
149
|
-
expect(
|
178
|
+
expect(query).to be_successful
|
179
|
+
expect(query.data["hello"]).to eq("world")
|
150
180
|
end
|
151
|
-
end
|
152
|
-
```
|
153
181
|
|
154
|
-
|
182
|
+
it "parses errors" do
|
183
|
+
query = schema.kaboom
|
155
184
|
|
156
|
-
|
157
|
-
|
158
|
-
|
185
|
+
expect(query).not_to be_successful
|
186
|
+
expect(query.errors[0].message).to eq("Invalid")
|
187
|
+
expect(query.errors[0].code).to eq("VALIDATION_ERROR")
|
188
|
+
end
|
159
189
|
end
|
160
190
|
```
|
161
191
|
|
data/graphql-extras.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
27
|
spec.add_dependency "activesupport", ">= 5.2"
|
28
|
-
spec.add_dependency "graphql", "~> 1.
|
28
|
+
spec.add_dependency "graphql", "~> 1.12"
|
29
29
|
spec.add_dependency "graphql-batch", "~> 0.4"
|
30
30
|
|
31
31
|
spec.add_development_dependency "bundler", "~> 2.0"
|
data/lib/graphql/extras.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "graphql/batch"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Extras
|
5
|
+
class AssociationLoader < GraphQL::Batch::Loader
|
6
|
+
def initialize(preload)
|
7
|
+
@preload = preload
|
8
|
+
end
|
9
|
+
|
10
|
+
def cache_key(record)
|
11
|
+
record.object_id
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform(records)
|
15
|
+
preloader = ActiveRecord::Associations::Preloader.new
|
16
|
+
preloader.preload(records, @preload)
|
17
|
+
|
18
|
+
records.each do |record|
|
19
|
+
fulfill(record, nil) unless fulfilled?(record)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "graphql/extras/association_loader"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Extras
|
5
|
+
module Preload
|
6
|
+
# @override
|
7
|
+
def initialize(*args, preload: nil, **opts, &block)
|
8
|
+
@preload = preload
|
9
|
+
super(*args, **opts, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @override
|
13
|
+
def resolve(object, args, ctx)
|
14
|
+
return super unless @preload
|
15
|
+
|
16
|
+
loader = AssociationLoader.for(@preload)
|
17
|
+
loader.load(object.object).then do
|
18
|
+
super(object, args, ctx)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "graphql/extras/test/schema"
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Extras
|
3
|
+
module Test
|
4
|
+
class Loader
|
5
|
+
FragmentNotFoundError = Class.new(StandardError)
|
6
|
+
|
7
|
+
attr_reader :fragments
|
8
|
+
attr_reader :operations
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@fragments = {}
|
12
|
+
@operations = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def load(path)
|
16
|
+
document = ::GraphQL.parse_file(path)
|
17
|
+
document.definitions.each do |node|
|
18
|
+
case node
|
19
|
+
when Nodes::FragmentDefinition
|
20
|
+
fragments[node.name] = node
|
21
|
+
when Nodes::OperationDefinition
|
22
|
+
operations[node.name] = node
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def print(operation)
|
28
|
+
printer = ::GraphQL::Language::Printer.new
|
29
|
+
nodes = [operation, *resolve_fragments(operation)]
|
30
|
+
nodes.map { |node| printer.print(node) }.join("\n")
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
Nodes = ::GraphQL::Language::Nodes
|
36
|
+
|
37
|
+
# Recursively iterate through the node's fields and find
|
38
|
+
# resolve all of the fragment definitions that are needed.
|
39
|
+
def resolve_fragments(node)
|
40
|
+
node.selections.flat_map do |field|
|
41
|
+
case field
|
42
|
+
when Nodes::FragmentSpread
|
43
|
+
fragment = fetch_fragment!(field.name)
|
44
|
+
[fragment, *resolve_fragments(fragment)]
|
45
|
+
else
|
46
|
+
resolve_fragments(field)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_fragment!(name)
|
52
|
+
fragments.fetch(name) do
|
53
|
+
raise FragmentNotFoundError, "Fragment `#{name}` is not defined"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Extras
|
3
|
+
module Test
|
4
|
+
class Response
|
5
|
+
attr_reader :data
|
6
|
+
attr_reader :errors
|
7
|
+
|
8
|
+
def initialize(payload)
|
9
|
+
@data = payload["data"]
|
10
|
+
@errors = payload.fetch("errors", []).map do |error|
|
11
|
+
Error.new(error)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def successful?
|
16
|
+
errors.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
class Error
|
20
|
+
attr_reader :message
|
21
|
+
attr_reader :extensions
|
22
|
+
attr_reader :code
|
23
|
+
attr_reader :path
|
24
|
+
attr_reader :locations
|
25
|
+
|
26
|
+
def initialize(payload)
|
27
|
+
@message = payload["message"]
|
28
|
+
@path = payload["path"]
|
29
|
+
@locations = payload["locations"]
|
30
|
+
@extensions = payload["extensions"]
|
31
|
+
@code = payload.dig("extensions", "code")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
require "active_support/inflector"
|
3
|
+
require "active_support/core_ext/hash/deep_transform_values"
|
4
|
+
require "graphql/extras/test/loader"
|
5
|
+
require "graphql/extras/test/response"
|
6
|
+
|
7
|
+
module GraphQL
|
8
|
+
module Extras
|
9
|
+
module Test
|
10
|
+
class Schema
|
11
|
+
def self.configure(schema:, queries:)
|
12
|
+
loader = Loader.new
|
13
|
+
|
14
|
+
Dir.glob(queries) do |path|
|
15
|
+
loader.load(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
loader.operations.each do |name, operation|
|
19
|
+
query = loader.print(operation)
|
20
|
+
|
21
|
+
define_method(name.underscore) do |variables = {}|
|
22
|
+
__execute(schema, query, variables)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(context = {})
|
28
|
+
@context = context
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def __execute(schema, query, variables)
|
34
|
+
uploads = {}
|
35
|
+
|
36
|
+
variables = variables.deep_transform_values do |value|
|
37
|
+
if value.respond_to? :tempfile
|
38
|
+
id = SecureRandom.uuid
|
39
|
+
uploads[id] = value
|
40
|
+
id
|
41
|
+
else
|
42
|
+
value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context = @context.merge(uploads: uploads)
|
47
|
+
result = schema.execute(query, variables: variables, context: context)
|
48
|
+
Response.new(result.to_h)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-extras
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ray Zane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.12'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.12'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: graphql-batch
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,9 +168,13 @@ files:
|
|
168
168
|
- bin/setup
|
169
169
|
- graphql-extras.gemspec
|
170
170
|
- lib/graphql/extras.rb
|
171
|
-
- lib/graphql/extras/
|
171
|
+
- lib/graphql/extras/association_loader.rb
|
172
172
|
- lib/graphql/extras/controller.rb
|
173
|
-
- lib/graphql/extras/
|
173
|
+
- lib/graphql/extras/preload.rb
|
174
|
+
- lib/graphql/extras/test.rb
|
175
|
+
- lib/graphql/extras/test/loader.rb
|
176
|
+
- lib/graphql/extras/test/response.rb
|
177
|
+
- lib/graphql/extras/test/schema.rb
|
174
178
|
- lib/graphql/extras/types.rb
|
175
179
|
- lib/graphql/extras/version.rb
|
176
180
|
homepage: https://github.com/promptworks/graphql-extras
|
data/lib/graphql/extras/batch.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require "graphql/batch"
|
2
|
-
|
3
|
-
module GraphQL
|
4
|
-
module Extras
|
5
|
-
module Batch
|
6
|
-
class AssociationLoader < GraphQL::Batch::Loader
|
7
|
-
def initialize(name, preload: name)
|
8
|
-
@name = name
|
9
|
-
@preload = preload
|
10
|
-
end
|
11
|
-
|
12
|
-
def cache_key(record)
|
13
|
-
record.object_id
|
14
|
-
end
|
15
|
-
|
16
|
-
def perform(records)
|
17
|
-
preloader = ActiveRecord::Associations::Preloader.new
|
18
|
-
preloader.preload(records, @preload)
|
19
|
-
|
20
|
-
records.each do |record|
|
21
|
-
fulfill(record, record.public_send(@name))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module Resolvers
|
27
|
-
def self.included(base)
|
28
|
-
base.extend ClassMethods
|
29
|
-
end
|
30
|
-
|
31
|
-
module ClassMethods
|
32
|
-
def association(name)
|
33
|
-
lambda do |record, _args, _ctx|
|
34
|
-
loader = AssociationLoader.for(name)
|
35
|
-
loader.load(record)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def association(record, name)
|
41
|
-
loader = AssociationLoader.for(name)
|
42
|
-
loader.load(record)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/graphql/extras/rspec.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require "active_support/inflector"
|
3
|
-
require "active_support/core_ext/hash"
|
4
|
-
|
5
|
-
module GraphQL
|
6
|
-
module Extras
|
7
|
-
module RSpec
|
8
|
-
class Queries
|
9
|
-
def add(key, value)
|
10
|
-
define_singleton_method(key) { value }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Schema
|
15
|
-
def initialize(schema, context: {})
|
16
|
-
@schema = schema
|
17
|
-
@context = context
|
18
|
-
end
|
19
|
-
|
20
|
-
def execute(query, variables = {})
|
21
|
-
variables = deep_camelize_keys(variables)
|
22
|
-
variables, uploads = extract_uploads(variables)
|
23
|
-
context = @context.merge(uploads: uploads)
|
24
|
-
|
25
|
-
result = @schema.execute(query, variables: variables, context: context)
|
26
|
-
result.to_h
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def extract_uploads(variables)
|
32
|
-
uploads = {}
|
33
|
-
variables = deep_transform_values(variables) { |value|
|
34
|
-
if upload?(value)
|
35
|
-
SecureRandom.hex.tap { |key| uploads.merge!(key => value) }
|
36
|
-
else
|
37
|
-
value
|
38
|
-
end
|
39
|
-
}
|
40
|
-
|
41
|
-
[variables, uploads]
|
42
|
-
end
|
43
|
-
|
44
|
-
def deep_camelize_keys(variables)
|
45
|
-
variables.deep_transform_keys { |key| key.to_s.camelize(:lower) }
|
46
|
-
end
|
47
|
-
|
48
|
-
def deep_transform_values(data, &block)
|
49
|
-
case data
|
50
|
-
when Array
|
51
|
-
data.map { |v| deep_transform_values(v, &block) }
|
52
|
-
when Hash
|
53
|
-
data.transform_values { |v| deep_transform_values(v, &block) }
|
54
|
-
else
|
55
|
-
yield data
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def upload?(value)
|
60
|
-
value.respond_to?(:tempfile) && value.respond_to?(:original_filename)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class Parser
|
65
|
-
include ::GraphQL::Language
|
66
|
-
|
67
|
-
def initialize(document)
|
68
|
-
@operations = document.definitions
|
69
|
-
.grep(Nodes::OperationDefinition)
|
70
|
-
|
71
|
-
@fragments = document.definitions
|
72
|
-
.grep(Nodes::FragmentDefinition)
|
73
|
-
.reduce({}) { |acc, f| acc.merge(f.name => f) }
|
74
|
-
end
|
75
|
-
|
76
|
-
def parse
|
77
|
-
queries = Queries.new
|
78
|
-
printer = Printer.new
|
79
|
-
|
80
|
-
@operations.each do |op|
|
81
|
-
nodes = [op, *find_fragments(op)]
|
82
|
-
nodes = nodes.map { |node| printer.print(node) }
|
83
|
-
queries.add op.name.underscore, nodes.join
|
84
|
-
end
|
85
|
-
|
86
|
-
queries
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def find_fragments(node)
|
92
|
-
node.selections.flat_map do |field|
|
93
|
-
if field.is_a? Nodes::FragmentSpread
|
94
|
-
fragment = @fragments.fetch(field.name)
|
95
|
-
[fragment, *find_fragments(fragment)]
|
96
|
-
else
|
97
|
-
find_fragments(field)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def graphql_fixture(filename)
|
104
|
-
root = ::RSpec.configuration.graphql_fixture_path
|
105
|
-
file = File.join(root, filename)
|
106
|
-
document = ::GraphQL.parse_file(file)
|
107
|
-
parser = Parser.new(document)
|
108
|
-
parser.parse
|
109
|
-
end
|
110
|
-
|
111
|
-
def use_schema(*args, **opts)
|
112
|
-
Schema.new(*args, **opts)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
RSpec::Matchers.define :be_successful_query do
|
119
|
-
match do |result|
|
120
|
-
result['errors'].nil?
|
121
|
-
end
|
122
|
-
|
123
|
-
failure_message do |result|
|
124
|
-
errors = result['errors'].map(&:deep_stringify_keys)
|
125
|
-
message = "expected query to be successful, but encountered errors:\n"
|
126
|
-
message + errors.to_yaml.lines.drop(1).join.indent(2)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
RSpec.configure do |config|
|
131
|
-
config.add_setting :graphql_fixture_path, default: "spec/fixtures/graphql"
|
132
|
-
config.include GraphQL::Extras::RSpec, type: :graphql
|
133
|
-
end
|