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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  4. data/.github/workflows/ci.yml +33 -29
  5. data/.github/workflows/danger-comment.yml +10 -0
  6. data/.github/workflows/danger.yml +13 -22
  7. data/.github/workflows/rubocop.yml +19 -19
  8. data/.gitignore +59 -52
  9. data/.rspec +1 -1
  10. data/.rubocop.yml +26 -28
  11. data/.rubocop_todo.yml +72 -48
  12. data/CHANGELOG.md +128 -107
  13. data/CONTRIBUTING.md +125 -125
  14. data/Dangerfile +24 -24
  15. data/Gemfile +35 -27
  16. data/LICENSE +21 -21
  17. data/README.md +800 -508
  18. data/RELEASING.md +63 -63
  19. data/Rakefile +15 -15
  20. data/UPGRADING.md +23 -23
  21. data/graphlient.gemspec +19 -19
  22. data/lib/graphlient/adapters/http/adapter.rb +41 -41
  23. data/lib/graphlient/adapters/http/faraday_adapter.rb +79 -45
  24. data/lib/graphlient/adapters/http/http_adapter.rb +40 -39
  25. data/lib/graphlient/adapters/http.rb +3 -3
  26. data/lib/graphlient/adapters.rb +1 -1
  27. data/lib/graphlient/client.rb +98 -73
  28. data/lib/graphlient/errors/client_error.rb +6 -6
  29. data/lib/graphlient/errors/connection_failed_error.rb +6 -6
  30. data/lib/graphlient/errors/error.rb +13 -12
  31. data/lib/graphlient/errors/execution_error.rb +29 -29
  32. data/lib/graphlient/errors/faraday_server_error.rb +12 -12
  33. data/lib/graphlient/errors/graphql_error.rb +53 -52
  34. data/lib/graphlient/errors/http_options_error.rb +6 -6
  35. data/lib/graphlient/errors/http_server_error.rb +13 -13
  36. data/lib/graphlient/errors/server_error.rb +7 -7
  37. data/lib/graphlient/errors/timeout_error.rb +6 -6
  38. data/lib/graphlient/errors.rb +10 -10
  39. data/lib/graphlient/extensions/query.rb +15 -15
  40. data/lib/graphlient/extensions.rb +1 -1
  41. data/lib/graphlient/query/directive.rb +47 -0
  42. data/lib/graphlient/query/serializer/arguments.rb +67 -0
  43. data/lib/graphlient/query/serializer/directives.rb +17 -0
  44. data/lib/graphlient/query/serializer/evaluator.rb +15 -0
  45. data/lib/graphlient/query/serializer/fragments.rb +28 -0
  46. data/lib/graphlient/query/serializer/scalars.rb +63 -0
  47. data/lib/graphlient/query/serializer.rb +153 -0
  48. data/lib/graphlient/query.rb +29 -128
  49. data/lib/graphlient/schema.rb +27 -26
  50. data/lib/graphlient/version.rb +3 -3
  51. data/lib/graphlient.rb +8 -8
  52. data/spec/graphlient/adapters/http/faraday_adapter_spec.rb +172 -112
  53. data/spec/graphlient/adapters/http/http_adapter_spec.rb +60 -60
  54. data/spec/graphlient/client_dsl_spec.rb +153 -0
  55. data/spec/graphlient/client_query_spec.rb +369 -346
  56. data/spec/graphlient/client_schema_spec.rb +75 -55
  57. data/spec/graphlient/extensions/query_spec.rb +16 -16
  58. data/spec/graphlient/github_query_spec.rb +32 -32
  59. data/spec/graphlient/query_dsl_spec.rb +231 -0
  60. data/spec/graphlient/query_spec.rb +105 -105
  61. data/spec/graphlient/schema_spec.rb +56 -56
  62. data/spec/graphlient/static_client_query_spec.rb +75 -68
  63. data/spec/graphlient/webmock_client_query_spec.rb +41 -41
  64. data/spec/spec_helper.rb +26 -14
  65. data/spec/support/context/dummy_client.rb +33 -26
  66. data/spec/support/context/github_client.rb +18 -18
  67. data/spec/support/dummy_app.rb +21 -19
  68. data/spec/support/dummy_schema.rb +17 -17
  69. data/spec/support/fixtures/github/schema.yml +14282 -14282
  70. data/spec/support/fixtures/github/user.yml +76 -76
  71. data/spec/support/fixtures/github/viewer.yml +76 -76
  72. data/spec/support/fixtures/invoice_api.json +1288 -1288
  73. data/spec/support/mutations/create_invoice.rb +18 -18
  74. data/spec/support/queries/query.rb +48 -47
  75. data/spec/support/schema/github.json +44479 -44479
  76. data/spec/support/types/invoice_type.rb +13 -13
  77. data/spec/support/types/mutation_type.rb +5 -5
  78. data/spec/support/vcr.rb +9 -9
  79. metadata +13 -8
  80. data/Gemfile.danger +0 -5
@@ -1,55 +1,75 @@
1
- require 'spec_helper'
2
- require 'tempfile'
3
-
4
- describe Graphlient::Client do
5
- let(:client) { described_class.new(url) }
6
- let(:url) { 'http://graph.biz/graphql' }
7
-
8
- describe '#schema' do
9
- before do
10
- stub_request(:post, url).to_return(
11
- body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
12
- headers: { 'Content-Type' => 'application/json' }
13
- )
14
- end
15
-
16
- context 'when server returns error' do
17
- before do
18
- stub_request(:post, url).to_return(
19
- status: 500,
20
- body: {
21
- errors: [
22
- { message: 'test message', extensions: { code: 'SOMETHING', timestamp: Time.now } }
23
- ]
24
- }.to_json,
25
- headers: { 'Content-Type' => 'application/json' }
26
- )
27
- end
28
-
29
- it 'fails with an exception' do
30
- expect do
31
- client.schema
32
- end.to raise_error Graphlient::Errors::FaradayServerError do |e|
33
- expect(e.to_s).to eq 'the server responded with status 500'
34
- expect(e.status_code).to eq 500
35
- expect(e.response['errors'].size).to eq 1
36
- expect(e.response['errors'].first['message']).to eq 'test message'
37
- end
38
- end
39
- end
40
-
41
- context 'when introspection request is sucessfull' do
42
- it 'returns Graphlient::Schema instance' do
43
- expect(client.schema).to be_a(Graphlient::Schema)
44
- end
45
- end
46
-
47
- context 'when schema path option is not String' do
48
- let(:client) { described_class.new(url, schema_path: Pathname.new('config/schema.json')) }
49
-
50
- it 'converts path to string' do
51
- expect(client.schema.path).to eq 'config/schema.json'
52
- end
53
- end
54
- end
55
- end
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Graphlient::Client do
5
+ let(:client) { described_class.new(url) }
6
+ let(:url) { 'http://graph.biz/graphql' }
7
+
8
+ describe '#schema' do
9
+ before do
10
+ stub_request(:post, url).to_return(
11
+ body: DummySchema.execute(GraphQL::Introspection::INTROSPECTION_QUERY).to_json,
12
+ headers: { 'Content-Type' => 'application/json' }
13
+ )
14
+ end
15
+
16
+ context 'when server returns error' do
17
+ before do
18
+ stub_request(:post, url).to_return(
19
+ status: 500,
20
+ body: {
21
+ errors: [
22
+ { message: 'test message', extensions: { code: 'SOMETHING', timestamp: Time.now } }
23
+ ]
24
+ }.to_json,
25
+ headers: { 'Content-Type' => 'application/json' }
26
+ )
27
+ end
28
+
29
+ it 'fails with an exception' do
30
+ expect do
31
+ client.schema
32
+ end.to raise_error Graphlient::Errors::FaradayServerError do |e|
33
+ expect(e.to_s).to include('the server responded with status 500')
34
+ expect(e.status_code).to eq 500
35
+ expect(e.response['errors'].size).to eq 1
36
+ expect(e.response['errors'].first['message']).to eq 'test message'
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'when introspection request is sucessfull' do
42
+ it 'returns Graphlient::Schema instance' do
43
+ expect(client.schema).to be_a(Graphlient::Schema)
44
+ end
45
+ end
46
+
47
+ context 'when schema path option is not String' do
48
+ let(:client) { described_class.new(url, schema_path: Pathname.new('config/schema.json')) }
49
+
50
+ it 'converts path to string' do
51
+ expect(client.schema.path).to eq 'config/schema.json'
52
+ end
53
+ end
54
+
55
+ context 'when preloaded schema is provided' do
56
+ let(:schema) { Graphlient::Schema.new(url, 'spec/support/fixtures/invoice_api.json') }
57
+ let(:client) { described_class.new(url, schema: schema) }
58
+
59
+ it 'returns the passed in schema' do
60
+ expect(client.schema).not_to be_nil
61
+ expect(client.schema).to eq(schema)
62
+ end
63
+ end
64
+
65
+ context 'when and a schema and a schema path are provided' do
66
+ let(:schema) { Graphlient::Schema.new(url, 'spec/support/fixtures/invoice_api.json') }
67
+ let(:client) { described_class.new(url, schema: schema, schema_path: 'spec/support/fixtures/invoice_api.json') }
68
+
69
+ it 'raises an invalid configuration error' do
70
+ expect { client }.to raise_error(Graphlient::Client::InvalidConfigurationError,
71
+ /schema_path and schema cannot both be provided/)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,16 +1,16 @@
1
- require 'spec_helper'
2
-
3
- describe Graphlient::Extensions::Query do
4
- describe 'Query' do
5
- include Graphlient::Extensions::Query
6
-
7
- it 'returns correct query' do
8
- query = query do
9
- invoice(id: 10) do
10
- line_items
11
- end
12
- end
13
- expect(query.to_s).to eq("query{\n invoice(id: 10){\n line_items\n }\n }")
14
- end
15
- end
16
- end
1
+ require 'spec_helper'
2
+
3
+ describe Graphlient::Extensions::Query do
4
+ describe 'Query' do
5
+ include Graphlient::Extensions::Query
6
+
7
+ it 'returns correct query' do
8
+ query = query do
9
+ invoice(id: 10) do
10
+ line_items
11
+ end
12
+ end
13
+ expect(query.to_s).to eq("query{\n invoice(id: 10){\n line_items\n }\n }")
14
+ end
15
+ end
16
+ end
@@ -1,32 +1,32 @@
1
- require 'spec_helper'
2
-
3
- describe Graphlient::Client do
4
- include_context 'Github Client'
5
-
6
- it 'has a schema', vcr: { cassette_name: 'github/schema' } do
7
- expect(client.schema).to be_a Graphlient::Schema
8
- end
9
-
10
- it 'queries current user', vcr: { cassette_name: 'github/viewer' } do
11
- rc = client.query <<-GRAPHQL
12
- query {
13
- viewer {
14
- name
15
- }
16
- }
17
- GRAPHQL
18
- expect(rc.data.viewer.name).to eq 'Daniel Doubrovkine (dB.) @dblockdotorg'
19
- end
20
-
21
- it 'queries with a parameter', vcr: { cassette_name: 'github/user' } do
22
- query = <<-GRAPHQL
23
- query($login: String!) {
24
- user(login: $login) {
25
- name
26
- }
27
- }
28
- GRAPHQL
29
- rc = client.query query, login: 'orta'
30
- expect(rc.data.user.name).to eq 'Orta'
31
- end
32
- end
1
+ require 'spec_helper'
2
+
3
+ describe Graphlient::Client do
4
+ include_context 'Github Client'
5
+
6
+ it 'has a schema', vcr: { cassette_name: 'github/schema' } do
7
+ expect(client.schema).to be_a Graphlient::Schema
8
+ end
9
+
10
+ it 'queries current user', vcr: { cassette_name: 'github/viewer' } do
11
+ rc = client.query <<-GRAPHQL
12
+ query {
13
+ viewer {
14
+ name
15
+ }
16
+ }
17
+ GRAPHQL
18
+ expect(rc.data.viewer.name).to eq 'Daniel Doubrovkine (dB.) @dblockdotorg'
19
+ end
20
+
21
+ it 'queries with a parameter', vcr: { cassette_name: 'github/user' } do
22
+ query = <<-GRAPHQL
23
+ query($login: String!) {
24
+ user(login: $login) {
25
+ name
26
+ }
27
+ }
28
+ GRAPHQL
29
+ rc = client.query query, login: 'orta'
30
+ expect(rc.data.user.name).to eq 'Orta'
31
+ end
32
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ # Specs for DSL extensions: directives, inline fragments, fragment definitions,
4
+ # spread + directive, and custom scalar registration.
5
+ # These operate on the Query string builder only -- no HTTP or schema access.
6
+
7
+ RSpec.describe Graphlient::Query do
8
+ def build(&block)
9
+ described_class.new(&block).to_s
10
+ end
11
+
12
+ # --- Directives -----------------------------------------------------------
13
+
14
+ describe 'directives (_name convention → @name)' do
15
+ it 'applies @skip to a field' do
16
+ result = build do
17
+ query(skip_fee: :boolean!) do
18
+ invoice(id: 10) do
19
+ id
20
+ feeInCents _skip(if: :skip_fee)
21
+ end
22
+ end
23
+ end
24
+ expect(result).to include('@skip(if: $skip_fee)')
25
+ expect(result).to include('feeInCents @skip(if: $skip_fee)')
26
+ end
27
+
28
+ it 'applies @include to a field' do
29
+ result = build do
30
+ query(show_fee: :boolean!) do
31
+ invoice(id: 10) do
32
+ feeInCents _include(if: :show_fee)
33
+ end
34
+ end
35
+ end
36
+ expect(result).to include('feeInCents @include(if: $show_fee)')
37
+ end
38
+
39
+ it 'applies multiple directives to one field' do
40
+ result = build do
41
+ query(skip_fee: :boolean!, show_desc: :boolean!) do
42
+ invoice(id: 10) do
43
+ feeInCents _skip(if: :skip_fee), _include(if: :show_desc)
44
+ end
45
+ end
46
+ end
47
+ expect(result).to include('@skip(if: $skip_fee)')
48
+ expect(result).to include('@include(if: $show_desc)')
49
+ end
50
+
51
+ it 'applies a directive with no arguments' do
52
+ result = build do
53
+ query do
54
+ invoice(id: 10) do
55
+ id _deprecated
56
+ end
57
+ end
58
+ end
59
+ expect(result).to include('id @deprecated')
60
+ end
61
+
62
+ it 'does not confuse ___ fragment constant with a directive' do
63
+ result = build do
64
+ query do
65
+ invoice(id: 10) { id }
66
+ end
67
+ end
68
+ expect(result).not_to include('@__')
69
+ end
70
+ end
71
+
72
+ # --- Fragment spreads with directives ------------------------------------
73
+
74
+ describe 'spread with directive' do
75
+ it 'appends directive after the spread name' do
76
+ result = build do
77
+ query(skip_invoice: :boolean!) do
78
+ spread :InvoiceFields, _skip(if: :skip_invoice)
79
+ end
80
+ end
81
+ expect(result).to include('...InvoiceFields @skip(if: $skip_invoice)')
82
+ end
83
+
84
+ it 'spread without directive is unchanged' do
85
+ result = build do
86
+ query { spread :InvoiceFields }
87
+ end
88
+ expect(result).to include('...InvoiceFields')
89
+ expect(result).not_to include('@')
90
+ end
91
+ end
92
+
93
+ # --- Inline fragments ----------------------------------------------------
94
+
95
+ # Inline fragments use the same `spread` verb as named fragment spreads, with the
96
+ # `on:` keyword (the same keyword as `fragment(name, on:)`) — one consistent entry point.
97
+ describe 'spread(on: :Type) — inline fragment' do
98
+ it 'generates ... on Type { }' do
99
+ result = build do
100
+ query do
101
+ invoice(id: 10) do
102
+ spread(on: :PaidInvoice) do
103
+ amountPaid
104
+ end
105
+ spread(on: :UnpaidInvoice) do
106
+ amountDue
107
+ end
108
+ end
109
+ end
110
+ end
111
+ expect(result).to include('... on PaidInvoice')
112
+ expect(result).to include('amountPaid')
113
+ expect(result).to include('... on UnpaidInvoice')
114
+ expect(result).to include('amountDue')
115
+ end
116
+
117
+ it 'applies a directive on the inline fragment' do
118
+ result = build do
119
+ query(skip_draft: :boolean!) do
120
+ invoice(id: 10) do
121
+ spread(_skip(if: :skip_draft), on: :DraftInvoice) do
122
+ draftId
123
+ end
124
+ end
125
+ end
126
+ end
127
+ expect(result).to include('... on DraftInvoice @skip(if: $skip_draft)')
128
+ expect(result).to include('draftId')
129
+ end
130
+
131
+ it 'inline fragment without block (bare type condition)' do
132
+ result = build do
133
+ query { spread(on: :Invoice) }
134
+ end
135
+ expect(result).to include('... on Invoice')
136
+ end
137
+ end
138
+
139
+ # --- spread argument validation -----------------------------------------
140
+
141
+ describe 'spread requires a name or an inline type condition' do
142
+ it 'raises when given neither a fragment name nor on:' do
143
+ expect { build { query { spread } } }
144
+ .to raise_error(Graphlient::Errors::Error, /requires a fragment name/)
145
+ end
146
+
147
+ it 'raises when a named spread is given a block' do
148
+ expect { build { query { spread(:InvoiceFields) { id } } } }
149
+ .to raise_error(Graphlient::Errors::Error, /takes no block/)
150
+ end
151
+ end
152
+
153
+ # --- Fragment definitions ------------------------------------------------
154
+
155
+ describe 'fragment(:Name, on: :Type)' do
156
+ it 'appends the fragment definition after the main query' do
157
+ result = build do
158
+ fragment(:InvoiceFields, on: :Invoice) do
159
+ id
160
+ feeInCents
161
+ end
162
+ query do
163
+ invoice(id: 10) do
164
+ spread :InvoiceFields
165
+ end
166
+ end
167
+ end
168
+ expect(result).to include('...InvoiceFields')
169
+ expect(result).to include('fragment InvoiceFields on Invoice')
170
+ expect(result).to include('feeInCents')
171
+ end
172
+
173
+ it 'separates query and fragment with a blank line' do
174
+ result = build do
175
+ fragment(:F, on: :T) { id }
176
+ query { spread :F }
177
+ end
178
+ parts = result.split("\n\n")
179
+ expect(parts.length).to eq 2
180
+ expect(parts.last).to start_with('fragment F on T')
181
+ end
182
+
183
+ it 'supports multiple fragment definitions' do
184
+ result = build do
185
+ fragment(:FragA, on: :TypeA) { field_a }
186
+ fragment(:FragB, on: :TypeB) { field_b }
187
+ query do
188
+ spread :FragA
189
+ spread :FragB
190
+ end
191
+ end
192
+ expect(result).to include('fragment FragA on TypeA')
193
+ expect(result).to include('fragment FragB on TypeB')
194
+ end
195
+ end
196
+
197
+ # --- Custom scalar registration ------------------------------------------
198
+
199
+ describe 'custom scalar registration' do
200
+ before { described_class::Serializer.scalar(:date, 'Date') }
201
+
202
+ it 'uses the registered type in variable declarations' do
203
+ result = build do
204
+ query(created_after: :date) do
205
+ invoices(created_after: :created_after) { id }
206
+ end
207
+ end
208
+ # Variable names are not camelized -- snake_case keys output as-is
209
+ expect(result).to include('$created_after: Date')
210
+ end
211
+
212
+ it 'supports non-null custom scalars with !' do
213
+ result = build do
214
+ query(started_at: :date!) do
215
+ invoices(started_at: :started_at) { id }
216
+ end
217
+ end
218
+ expect(result).to include('$started_at: Date!')
219
+ end
220
+
221
+ it 'built-in scalars still work alongside custom ones' do
222
+ result = build do
223
+ query(id: :int, created_after: :date) do
224
+ invoice(id: :id) { id }
225
+ end
226
+ end
227
+ expect(result).to include('$id: Int')
228
+ expect(result).to include('$created_after: Date')
229
+ end
230
+ end
231
+ end
@@ -1,105 +1,105 @@
1
- require 'spec_helper'
2
-
3
- describe Graphlient::Query do
4
- describe '#initialize' do
5
- context 'query' do
6
- it 'returns expected query with block' do
7
- query = Graphlient::Query.new do
8
- query do
9
- invoice do
10
- line_items
11
- end
12
- end
13
- end
14
- expect(query.to_s).to eq "query{\n invoice{\n line_items\n }\n }"
15
- end
16
-
17
- it 'returns expected query with block and attributes' do
18
- query = Graphlient::Query.new do
19
- query do
20
- invoice(id: 10) do
21
- line_items
22
- end
23
- end
24
- end
25
- expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items\n }\n }"
26
- end
27
-
28
- it 'returns expected query with block and attributes' do
29
- query = Graphlient::Query.new do
30
- query do
31
- invoice(id: 10) do
32
- line_items(name: 'test')
33
- end
34
- end
35
- end
36
- expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items(name: \"test\")\n }\n }"
37
- end
38
-
39
- it 'returns expected query with block and local variables with proper type' do
40
- int_arg = 10
41
- float_arg = 10.3
42
- str_arg = 'new name'
43
- array_arg = ['str_item', 2]
44
- query = Graphlient::Query.new do
45
- query do
46
- invoice(id: int_arg, threshold: float_arg, item_list: array_arg) do
47
- line_items(name: str_arg)
48
- end
49
- end
50
- end
51
- expect(query.to_s).to eq "query{\n invoice(id: 10, threshold: 10.3, item_list: [\"str_item\", 2]){\n line_items(name: \"new name\")\n }\n }"
52
- end
53
-
54
- it 'returns proper query' do
55
- query = Graphlient::Query.new do
56
- query do
57
- invoice(id: 10) do
58
- line_items do
59
- line_item_type
60
- end
61
- end
62
- end
63
- end
64
- expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items{\n line_item_type\n }\n }\n }"
65
- end
66
-
67
- it 'returns proper query with query variables' do
68
- query = Graphlient::Query.new do
69
- query(invoice_id: :int, names: [:string!]) do
70
- invoice(id: :invoice_id, name: :names) do
71
- line_items do
72
- line_item_type
73
- end
74
- end
75
- end
76
- end
77
- expect(query.to_s).to eq "query($invoice_id: Int, $names: [String!]){\n invoice(id: $invoice_id, name: $names){\n line_items{\n line_item_type\n }\n }\n }"
78
- end
79
- end
80
-
81
- context 'mutation' do
82
- it 'returns proper mutation with arguments' do
83
- mutation = Graphlient::Query.new do
84
- mutation do
85
- invoice(type: 'test', fee_in_cents: 20_000, total_cents: 50_000, line_items: %w[li1 li2]) do
86
- id
87
- end
88
- end
89
- end
90
- expect(mutation.to_s).to eq "mutation{\n invoice(type: \"test\", fee_in_cents: 20000, total_cents: 50000, line_items: [\"li1\", \"li2\"]){\n id\n }\n }"
91
- end
92
- end
93
-
94
- it 'returns proper mutation for relay style mutation' do
95
- mutation = Graphlient::Query.new do
96
- mutation do
97
- invoice(input: { type: 'test', fee_in_cents: 20_000, total_cents: 50_000, line_items: %w[li1 li2] }) do
98
- id
99
- end
100
- end
101
- end
102
- expect(mutation.to_s).to eq "mutation{\n invoice(input: { type: \"test\", fee_in_cents: 20000, total_cents: 50000, line_items: [\"li1\", \"li2\"] }){\n id\n }\n }"
103
- end
104
- end
105
- end
1
+ require 'spec_helper'
2
+
3
+ describe Graphlient::Query do
4
+ describe '#initialize' do
5
+ context 'query' do
6
+ it 'returns expected query with block' do
7
+ query = Graphlient::Query.new do
8
+ query do
9
+ invoice do
10
+ line_items
11
+ end
12
+ end
13
+ end
14
+ expect(query.to_s).to eq "query{\n invoice{\n line_items\n }\n }"
15
+ end
16
+
17
+ it 'returns expected query with block and attributes' do
18
+ query = Graphlient::Query.new do
19
+ query do
20
+ invoice(id: 10) do
21
+ line_items
22
+ end
23
+ end
24
+ end
25
+ expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items\n }\n }"
26
+ end
27
+
28
+ it 'returns expected query with block and attributes' do
29
+ query = Graphlient::Query.new do
30
+ query do
31
+ invoice(id: 10) do
32
+ line_items(name: 'test')
33
+ end
34
+ end
35
+ end
36
+ expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items(name: \"test\")\n }\n }"
37
+ end
38
+
39
+ it 'returns expected query with block and local variables with proper type' do
40
+ int_arg = 10
41
+ float_arg = 10.3
42
+ str_arg = 'new name'
43
+ array_arg = ['str_item', 2]
44
+ query = Graphlient::Query.new do
45
+ query do
46
+ invoice(id: int_arg, threshold: float_arg, item_list: array_arg) do
47
+ line_items(name: str_arg)
48
+ end
49
+ end
50
+ end
51
+ expect(query.to_s).to eq "query{\n invoice(id: 10, threshold: 10.3, item_list: [\"str_item\", 2]){\n line_items(name: \"new name\")\n }\n }"
52
+ end
53
+
54
+ it 'returns proper query' do
55
+ query = Graphlient::Query.new do
56
+ query do
57
+ invoice(id: 10) do
58
+ line_items do
59
+ line_item_type
60
+ end
61
+ end
62
+ end
63
+ end
64
+ expect(query.to_s).to eq "query{\n invoice(id: 10){\n line_items{\n line_item_type\n }\n }\n }"
65
+ end
66
+
67
+ it 'returns proper query with query variables' do
68
+ query = Graphlient::Query.new do
69
+ query(invoice_id: :int, names: [:string!]) do
70
+ invoice(id: :invoice_id, name: :names) do
71
+ line_items do
72
+ line_item_type
73
+ end
74
+ end
75
+ end
76
+ end
77
+ expect(query.to_s).to eq "query($invoice_id: Int, $names: [String!]){\n invoice(id: $invoice_id, name: $names){\n line_items{\n line_item_type\n }\n }\n }"
78
+ end
79
+ end
80
+
81
+ context 'mutation' do
82
+ it 'returns proper mutation with arguments' do
83
+ mutation = Graphlient::Query.new do
84
+ mutation do
85
+ invoice(type: 'test', fee_in_cents: 20_000, total_cents: 50_000, line_items: %w[li1 li2]) do
86
+ id
87
+ end
88
+ end
89
+ end
90
+ expect(mutation.to_s).to eq "mutation{\n invoice(type: \"test\", fee_in_cents: 20000, total_cents: 50000, line_items: [\"li1\", \"li2\"]){\n id\n }\n }"
91
+ end
92
+ end
93
+
94
+ it 'returns proper mutation for relay style mutation' do
95
+ mutation = Graphlient::Query.new do
96
+ mutation do
97
+ invoice(input: { type: 'test', fee_in_cents: 20_000, total_cents: 50_000, line_items: %w[li1 li2] }) do
98
+ id
99
+ end
100
+ end
101
+ end
102
+ expect(mutation.to_s).to eq "mutation{\n invoice(input: { type: \"test\", fee_in_cents: 20000, total_cents: 50000, line_items: [\"li1\", \"li2\"] }){\n id\n }\n }"
103
+ end
104
+ end
105
+ end