graphlient 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
- data/.github/workflows/ci.yml +33 -29
- data/.github/workflows/danger-comment.yml +10 -0
- data/.github/workflows/danger.yml +13 -22
- data/.github/workflows/rubocop.yml +19 -19
- data/.gitignore +59 -52
- data/.rspec +1 -1
- data/.rubocop.yml +26 -28
- data/.rubocop_todo.yml +72 -48
- data/CHANGELOG.md +128 -107
- data/CONTRIBUTING.md +125 -125
- data/Dangerfile +24 -24
- data/Gemfile +35 -27
- data/LICENSE +21 -21
- data/README.md +800 -508
- data/RELEASING.md +63 -63
- data/Rakefile +15 -15
- data/UPGRADING.md +23 -23
- data/graphlient.gemspec +19 -19
- data/lib/graphlient/adapters/http/adapter.rb +41 -41
- data/lib/graphlient/adapters/http/faraday_adapter.rb +79 -45
- data/lib/graphlient/adapters/http/http_adapter.rb +40 -39
- data/lib/graphlient/adapters/http.rb +3 -3
- data/lib/graphlient/adapters.rb +1 -1
- data/lib/graphlient/client.rb +98 -73
- data/lib/graphlient/errors/client_error.rb +6 -6
- data/lib/graphlient/errors/connection_failed_error.rb +6 -6
- data/lib/graphlient/errors/error.rb +13 -12
- data/lib/graphlient/errors/execution_error.rb +29 -29
- data/lib/graphlient/errors/faraday_server_error.rb +12 -12
- data/lib/graphlient/errors/graphql_error.rb +53 -52
- data/lib/graphlient/errors/http_options_error.rb +6 -6
- data/lib/graphlient/errors/http_server_error.rb +13 -13
- data/lib/graphlient/errors/server_error.rb +7 -7
- data/lib/graphlient/errors/timeout_error.rb +6 -6
- data/lib/graphlient/errors.rb +10 -10
- data/lib/graphlient/extensions/query.rb +15 -15
- data/lib/graphlient/extensions.rb +1 -1
- data/lib/graphlient/query/directive.rb +47 -0
- data/lib/graphlient/query/serializer/arguments.rb +67 -0
- data/lib/graphlient/query/serializer/directives.rb +17 -0
- data/lib/graphlient/query/serializer/evaluator.rb +15 -0
- data/lib/graphlient/query/serializer/fragments.rb +28 -0
- data/lib/graphlient/query/serializer/scalars.rb +63 -0
- data/lib/graphlient/query/serializer.rb +153 -0
- data/lib/graphlient/query.rb +29 -128
- data/lib/graphlient/schema.rb +27 -26
- data/lib/graphlient/version.rb +3 -3
- data/lib/graphlient.rb +8 -8
- data/spec/graphlient/adapters/http/faraday_adapter_spec.rb +172 -112
- data/spec/graphlient/adapters/http/http_adapter_spec.rb +60 -60
- data/spec/graphlient/client_dsl_spec.rb +153 -0
- data/spec/graphlient/client_query_spec.rb +369 -346
- data/spec/graphlient/client_schema_spec.rb +75 -55
- data/spec/graphlient/extensions/query_spec.rb +16 -16
- data/spec/graphlient/github_query_spec.rb +32 -32
- data/spec/graphlient/query_dsl_spec.rb +231 -0
- data/spec/graphlient/query_spec.rb +105 -105
- data/spec/graphlient/schema_spec.rb +56 -56
- data/spec/graphlient/static_client_query_spec.rb +75 -68
- data/spec/graphlient/webmock_client_query_spec.rb +41 -41
- data/spec/spec_helper.rb +26 -14
- data/spec/support/context/dummy_client.rb +33 -26
- data/spec/support/context/github_client.rb +18 -18
- data/spec/support/dummy_app.rb +21 -19
- data/spec/support/dummy_schema.rb +17 -17
- data/spec/support/fixtures/github/schema.yml +14282 -14282
- data/spec/support/fixtures/github/user.yml +76 -76
- data/spec/support/fixtures/github/viewer.yml +76 -76
- data/spec/support/fixtures/invoice_api.json +1288 -1288
- data/spec/support/mutations/create_invoice.rb +18 -18
- data/spec/support/queries/query.rb +48 -47
- data/spec/support/schema/github.json +44479 -44479
- data/spec/support/types/invoice_type.rb +13 -13
- data/spec/support/types/mutation_type.rb +5 -5
- data/spec/support/vcr.rb +9 -9
- metadata +13 -8
- data/Gemfile.danger +0 -5
|
@@ -1,112 +1,172 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Graphlient::Adapters::HTTP::FaradayAdapter do
|
|
4
|
-
let(:app) { Object.new }
|
|
5
|
-
|
|
6
|
-
context 'with a custom middleware' do
|
|
7
|
-
let(:client) do
|
|
8
|
-
Graphlient::Client.new('http://example.com/graphql') do |client|
|
|
9
|
-
client.http do |h|
|
|
10
|
-
h.connection do |c|
|
|
11
|
-
c.adapter Faraday::Adapter::Rack, app
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'inserts a middleware into the connection' do
|
|
18
|
-
expect(client.http.connection.adapter).to eq Faraday::Adapter::Rack
|
|
19
|
-
expect(client.http.connection.builder.handlers).to eq(
|
|
20
|
-
[
|
|
21
|
-
Faraday::Response::RaiseError,
|
|
22
|
-
Faraday::Request::Json,
|
|
23
|
-
Faraday::Response::Json
|
|
24
|
-
]
|
|
25
|
-
)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context 'with custom url, headers and http_options' do
|
|
30
|
-
let(:url) { 'http://example.com/graphql' }
|
|
31
|
-
let(:headers) { { 'Foo' => 'bar' } }
|
|
32
|
-
let(:http_options) { { timeout: timeout, write_timeout: write_timeout } }
|
|
33
|
-
let(:timeout) { 123 }
|
|
34
|
-
let(:write_timeout) { 234 }
|
|
35
|
-
let(:client) do
|
|
36
|
-
Graphlient::Client.new(url, headers: headers, http_options: http_options)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it 'sets url' do
|
|
40
|
-
expect(client.http.url).to eq url
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'sets headers' do
|
|
44
|
-
expect(client.http.headers).to eq headers
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it 'sets http_options' do
|
|
48
|
-
expect(client.http.connection.options.timeout).to eq(timeout)
|
|
49
|
-
expect(client.http.connection.options.write_timeout).to eq(write_timeout)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context 'when http_options contains invalid option' do
|
|
53
|
-
let(:http_options) { { an_invalid_option: 'an invalid option' } }
|
|
54
|
-
|
|
55
|
-
it 'raises Graphlient::Errors::HttpOptionsError' do
|
|
56
|
-
expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context 'default' do
|
|
62
|
-
let(:url) { 'http://example.com/graphql' }
|
|
63
|
-
let(:client) { Graphlient::Client.new(url) }
|
|
64
|
-
|
|
65
|
-
before do
|
|
66
|
-
stub_request(:post, url).to_return(
|
|
67
|
-
status: 200,
|
|
68
|
-
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
|
|
69
|
-
headers: { 'Content-Type' => 'application/json' }
|
|
70
|
-
)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it 'retrieves schema' do
|
|
74
|
-
expect(client.schema).to be_a Graphlient::Schema
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
context '
|
|
79
|
-
let(:url) { 'http://example.com/graphql' }
|
|
80
|
-
let(:
|
|
81
|
-
let(:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
expect
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
end
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Graphlient::Adapters::HTTP::FaradayAdapter do
|
|
4
|
+
let(:app) { Object.new }
|
|
5
|
+
|
|
6
|
+
context 'with a custom middleware' do
|
|
7
|
+
let(:client) do
|
|
8
|
+
Graphlient::Client.new('http://example.com/graphql') do |client|
|
|
9
|
+
client.http do |h|
|
|
10
|
+
h.connection do |c|
|
|
11
|
+
c.adapter Faraday::Adapter::Rack, app
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'inserts a middleware into the connection' do
|
|
18
|
+
expect(client.http.connection.adapter).to eq Faraday::Adapter::Rack
|
|
19
|
+
expect(client.http.connection.builder.handlers).to eq(
|
|
20
|
+
[
|
|
21
|
+
Faraday::Response::RaiseError,
|
|
22
|
+
Faraday::Request::Json,
|
|
23
|
+
Faraday::Response::Json
|
|
24
|
+
]
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'with custom url, headers and http_options' do
|
|
30
|
+
let(:url) { 'http://example.com/graphql' }
|
|
31
|
+
let(:headers) { { 'Foo' => 'bar' } }
|
|
32
|
+
let(:http_options) { { timeout: timeout, write_timeout: write_timeout } }
|
|
33
|
+
let(:timeout) { 123 }
|
|
34
|
+
let(:write_timeout) { 234 }
|
|
35
|
+
let(:client) do
|
|
36
|
+
Graphlient::Client.new(url, headers: headers, http_options: http_options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'sets url' do
|
|
40
|
+
expect(client.http.url).to eq url
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'sets headers' do
|
|
44
|
+
expect(client.http.headers).to eq headers
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'sets http_options' do
|
|
48
|
+
expect(client.http.connection.options.timeout).to eq(timeout)
|
|
49
|
+
expect(client.http.connection.options.write_timeout).to eq(write_timeout)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when http_options contains invalid option' do
|
|
53
|
+
let(:http_options) { { an_invalid_option: 'an invalid option' } }
|
|
54
|
+
|
|
55
|
+
it 'raises Graphlient::Errors::HttpOptionsError' do
|
|
56
|
+
expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'default' do
|
|
62
|
+
let(:url) { 'http://example.com/graphql' }
|
|
63
|
+
let(:client) { Graphlient::Client.new(url) }
|
|
64
|
+
|
|
65
|
+
before do
|
|
66
|
+
stub_request(:post, url).to_return(
|
|
67
|
+
status: 200,
|
|
68
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
|
|
69
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'retrieves schema' do
|
|
74
|
+
expect(client.schema).to be_a Graphlient::Schema
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'a non-error response without an appropriate JSON header' do
|
|
79
|
+
let(:url) { 'http://example.com/graphql' }
|
|
80
|
+
let(:headers) { { 'Content-Type' => 'application/notjson' } }
|
|
81
|
+
let(:client) { Graphlient::Client.new(url) }
|
|
82
|
+
let(:response_headers) { { 'Content-Type' => 'application/notjson' } }
|
|
83
|
+
|
|
84
|
+
context 'when the response body is valid JSON' do
|
|
85
|
+
before do
|
|
86
|
+
stub_request(:post, url).to_return(
|
|
87
|
+
status: 200,
|
|
88
|
+
headers: response_headers,
|
|
89
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'retrieves schema' do
|
|
94
|
+
expect(client.schema).to be_a Graphlient::Schema
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'when the response body is not valid JSON' do
|
|
99
|
+
before do
|
|
100
|
+
stub_request(:post, url).to_return(
|
|
101
|
+
status: 200,
|
|
102
|
+
headers: response_headers,
|
|
103
|
+
body: ''
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'raises Graphlient::Errors::ServerError' do
|
|
108
|
+
expect { client.schema }.to raise_error(Graphlient::Errors::ServerError) { |error|
|
|
109
|
+
expect(error.message).to include('Failed to parse response body as JSON')
|
|
110
|
+
}
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context 'when the Faraday response body object is not a type we expect from Faraday' do
|
|
115
|
+
before do
|
|
116
|
+
stub_request(:post, url).to_return(
|
|
117
|
+
status: 200,
|
|
118
|
+
headers: response_headers
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'raises Graphlient::Errors::ClientError' do
|
|
123
|
+
mock_response = double('response', body: nil)
|
|
124
|
+
allow(client.http.connection).to receive(:post).and_return(mock_response)
|
|
125
|
+
|
|
126
|
+
expect { client.schema }.to raise_error(Graphlient::Errors::ClientError) { |error|
|
|
127
|
+
expect(error.message).to include "Unexpected response body type 'NilClass'"
|
|
128
|
+
}
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context 'Failed to open TCP connection error' do
|
|
134
|
+
let(:url) { 'http://example.com/graphql' }
|
|
135
|
+
let(:client) { Graphlient::Client.new(url) }
|
|
136
|
+
let(:error_message) do
|
|
137
|
+
'Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)'
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
before do
|
|
141
|
+
wrapped_error = Errno::ECONNREFUSED.new(error_message)
|
|
142
|
+
error = Faraday::ConnectionFailed.new(wrapped_error)
|
|
143
|
+
|
|
144
|
+
stub_request(:post, url).to_raise(error)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
specify do
|
|
148
|
+
# Use a regex so the test passes on both Linux ("Connection refused - ...")
|
|
149
|
+
# and Windows (where Errno::ECONNREFUSED prepends a different OS message).
|
|
150
|
+
# Both platforms include the core error_message string in the result.
|
|
151
|
+
expect { client.schema }.to raise_error(
|
|
152
|
+
Graphlient::Errors::ConnectionFailedError,
|
|
153
|
+
/#{Regexp.escape(error_message)}/
|
|
154
|
+
)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context 'Faraday Timeout Error' do
|
|
159
|
+
let(:url) { 'http://example.com/graphql' }
|
|
160
|
+
let(:client) { Graphlient::Client.new(url) }
|
|
161
|
+
let(:error_message) { 'Failed to Connect' }
|
|
162
|
+
|
|
163
|
+
before do
|
|
164
|
+
stub_request(:post, url).to_raise(Faraday::TimeoutError.new(Net::ReadTimeout.new(error_message)))
|
|
165
|
+
end
|
|
166
|
+
it 'raises a Graphlient Timeout' do
|
|
167
|
+
expect { client.schema }.to raise_error(Graphlient::Errors::TimeoutError) { |error|
|
|
168
|
+
expect(error.message).to include(error_message)
|
|
169
|
+
}
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Graphlient::Adapters::HTTP::HTTPAdapter do
|
|
4
|
-
let(:app) { Object.new }
|
|
5
|
-
|
|
6
|
-
context 'with custom url, headers and http_options' do
|
|
7
|
-
let(:url) { 'http://example.com/graphql' }
|
|
8
|
-
let(:headers) { { 'Foo' => 'bar' } }
|
|
9
|
-
let(:http_options) { { read_timeout: read_timeout } }
|
|
10
|
-
let(:read_timeout) { nil }
|
|
11
|
-
let(:client) do
|
|
12
|
-
Graphlient::Client.new(
|
|
13
|
-
url,
|
|
14
|
-
headers: headers,
|
|
15
|
-
http_options: http_options,
|
|
16
|
-
http: Graphlient::Adapters::HTTP::HTTPAdapter
|
|
17
|
-
)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'sets adapter' do
|
|
21
|
-
expect(client.http).to be_a Graphlient::Adapters::HTTP::HTTPAdapter
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'sets url' do
|
|
25
|
-
expect(client.http.url).to eq url
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'sets headers' do
|
|
29
|
-
expect(client.http.headers).to eq headers
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'sets http_options' do
|
|
33
|
-
expect(client.http.connection.read_timeout).to eq(read_timeout)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
context 'when http_options contains invalid option' do
|
|
37
|
-
let(:http_options) { { an_invalid_option: 'an invalid option' } }
|
|
38
|
-
|
|
39
|
-
it 'raises Graphlient::Errors::HttpOptionsError' do
|
|
40
|
-
expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
context 'default' do
|
|
46
|
-
let(:url) { 'http://example.com/graphql' }
|
|
47
|
-
let(:client) { Graphlient::Client.new(url, http: Graphlient::Adapters::HTTP::HTTPAdapter) }
|
|
48
|
-
|
|
49
|
-
before do
|
|
50
|
-
stub_request(:post, url).to_return(
|
|
51
|
-
status: 200,
|
|
52
|
-
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'retrieves schema' do
|
|
57
|
-
expect(client.schema).to be_a Graphlient::Schema
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Graphlient::Adapters::HTTP::HTTPAdapter do
|
|
4
|
+
let(:app) { Object.new }
|
|
5
|
+
|
|
6
|
+
context 'with custom url, headers and http_options' do
|
|
7
|
+
let(:url) { 'http://example.com/graphql' }
|
|
8
|
+
let(:headers) { { 'Foo' => 'bar' } }
|
|
9
|
+
let(:http_options) { { read_timeout: read_timeout } }
|
|
10
|
+
let(:read_timeout) { nil }
|
|
11
|
+
let(:client) do
|
|
12
|
+
Graphlient::Client.new(
|
|
13
|
+
url,
|
|
14
|
+
headers: headers,
|
|
15
|
+
http_options: http_options,
|
|
16
|
+
http: Graphlient::Adapters::HTTP::HTTPAdapter
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'sets adapter' do
|
|
21
|
+
expect(client.http).to be_a Graphlient::Adapters::HTTP::HTTPAdapter
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'sets url' do
|
|
25
|
+
expect(client.http.url).to eq url
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'sets headers' do
|
|
29
|
+
expect(client.http.headers).to eq headers
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'sets http_options' do
|
|
33
|
+
expect(client.http.connection.read_timeout).to eq(read_timeout)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when http_options contains invalid option' do
|
|
37
|
+
let(:http_options) { { an_invalid_option: 'an invalid option' } }
|
|
38
|
+
|
|
39
|
+
it 'raises Graphlient::Errors::HttpOptionsError' do
|
|
40
|
+
expect { client.http.connection }.to raise_error(Graphlient::Errors::HttpOptionsError)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'default' do
|
|
46
|
+
let(:url) { 'http://example.com/graphql' }
|
|
47
|
+
let(:client) { Graphlient::Client.new(url, http: Graphlient::Adapters::HTTP::HTTPAdapter) }
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
stub_request(:post, url).to_return(
|
|
51
|
+
status: 200,
|
|
52
|
+
body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'retrieves schema' do
|
|
57
|
+
expect(client.schema).to be_a Graphlient::Schema
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Graphlient::Client do
|
|
4
|
+
let(:client) { described_class.new('http://example.com/graphql') }
|
|
5
|
+
|
|
6
|
+
describe '#to_query_string' do
|
|
7
|
+
it 'returns a String' do
|
|
8
|
+
result = client.to_query_string do
|
|
9
|
+
query do
|
|
10
|
+
invoice(id: 10) do
|
|
11
|
+
id
|
|
12
|
+
feeInCents
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
expect(result).to be_a String
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'builds a simple query without HTTP or schema access' do
|
|
20
|
+
result = client.to_query_string do
|
|
21
|
+
query do
|
|
22
|
+
invoice(id: 10) do
|
|
23
|
+
id
|
|
24
|
+
feeInCents
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
expect(result).to include('query')
|
|
29
|
+
expect(result).to include('invoice')
|
|
30
|
+
expect(result).to include('feeInCents')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'builds a parameterized query with variable declarations' do
|
|
34
|
+
result = client.to_query_string do
|
|
35
|
+
query(id: :int) do
|
|
36
|
+
invoice(id: :id) do
|
|
37
|
+
id
|
|
38
|
+
feeInCents
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
expect(result).to include('$id: Int')
|
|
43
|
+
expect(result).to include('invoice(id: $id)')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'builds a mutation query string' do
|
|
47
|
+
result = client.to_query_string do
|
|
48
|
+
mutation(input: :CreateInvoiceInput!) do
|
|
49
|
+
createInvoice(input: :input) do
|
|
50
|
+
invoice do
|
|
51
|
+
id
|
|
52
|
+
end
|
|
53
|
+
errors
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
expect(result).to include('mutation')
|
|
58
|
+
expect(result).to include('createInvoice')
|
|
59
|
+
expect(result).to include('$input: CreateInvoiceInput!')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'does not interact with the HTTP adapter' do
|
|
63
|
+
expect_any_instance_of(Graphlient::Adapters::HTTP::FaradayAdapter).not_to receive(:execute)
|
|
64
|
+
client.to_query_string do
|
|
65
|
+
query do
|
|
66
|
+
invoice(id: 1) { id }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'with spread helper' do
|
|
72
|
+
it 'includes a named fragment spread in the query string' do
|
|
73
|
+
result = client.to_query_string do
|
|
74
|
+
query do
|
|
75
|
+
invoice(id: 10) do
|
|
76
|
+
spread :InvoiceFields
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
expect(result).to include('...InvoiceFields')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'supports multiple spreads at the same level' do
|
|
84
|
+
result = client.to_query_string do
|
|
85
|
+
query do
|
|
86
|
+
nodes do
|
|
87
|
+
spread :FragmentA
|
|
88
|
+
spread :FragmentB
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
expect(result).to include('...FragmentA')
|
|
93
|
+
expect(result).to include('...FragmentB')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'builds a query with a directive' do
|
|
98
|
+
result = client.to_query_string do
|
|
99
|
+
query(skip_fee: :boolean!) do
|
|
100
|
+
invoice(id: 10) do
|
|
101
|
+
id
|
|
102
|
+
feeInCents _skip(if: :skip_fee)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
expect(result).to include('feeInCents @skip(if: $skip_fee)')
|
|
107
|
+
expect(result).to include('$skip_fee: Boolean!')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'builds a query with an inline fragment' do
|
|
111
|
+
result = client.to_query_string do
|
|
112
|
+
query do
|
|
113
|
+
invoice(id: 10) do
|
|
114
|
+
spread(on: :PaidInvoice) { amountPaid }
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
expect(result).to include('... on PaidInvoice')
|
|
119
|
+
expect(result).to include('amountPaid')
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'builds a query with an inline fragment definition' do
|
|
123
|
+
result = client.to_query_string do
|
|
124
|
+
fragment(:InvoiceFields, on: :Invoice) do
|
|
125
|
+
id
|
|
126
|
+
feeInCents
|
|
127
|
+
end
|
|
128
|
+
query { invoice(id: 10) { spread :InvoiceFields } }
|
|
129
|
+
end
|
|
130
|
+
expect(result).to include('...InvoiceFields')
|
|
131
|
+
expect(result).to include('fragment InvoiceFields on Invoice')
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
describe '#scalar (custom scalar registration)' do
|
|
136
|
+
let(:client_with_scalars) do
|
|
137
|
+
described_class.new('http://example.com/graphql') do |c|
|
|
138
|
+
c.scalar :date, 'Date'
|
|
139
|
+
c.scalar :uuid, 'UUID'
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'registers custom scalars via the client block' do
|
|
144
|
+
result = client_with_scalars.to_query_string do
|
|
145
|
+
query(created_after: :date, id: :uuid!) do
|
|
146
|
+
invoices(created_after: :created_after) { total }
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
expect(result).to include('$created_after: Date')
|
|
150
|
+
expect(result).to include('$id: UUID!')
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|