rspec-graphql-integration 0.1.0 → 0.2.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c741c1c9dcf41ac20bad890effdfde5ffa121b63b60f6704f07c0638a6001e6e
|
4
|
+
data.tar.gz: 74742a1424ec5ff2587bf945eab4cc5bf8ea059552da4f9b61ef01676b284477
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1dc6131393b96403f4054cb9a75c9d44c00a23dc6e5b101525290f1ba9f55d05b8ac4e3d071df262c14f53c4508d7a6f72357a10ca30eb611e1ad760fa3aa7bd
|
7
|
+
data.tar.gz: c6ed7377e513b4e12589f0ae8f1986bbedfbe8c43c31e773427e7b96926089ecac242b930cab4c858994b001776625e34af078b2fb56e2fed42931884b8acebb
|
@@ -4,6 +4,7 @@ module RSpec
|
|
4
4
|
module GraphqlIntegration
|
5
5
|
def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength
|
6
6
|
config.add_setting(:graphql_schema_class, default: nil)
|
7
|
+
config.add_setting(:graphql_put_files_in_folder, default: false)
|
7
8
|
|
8
9
|
config.include(RSpec::GraphqlIntegration::Matchers::DeepEq, type: :graphql)
|
9
10
|
config.include(RSpec::GraphqlIntegration::Matchers::MatchGraphqlResponse, type: :graphql)
|
@@ -2,12 +2,10 @@ module RSpec
|
|
2
2
|
module GraphqlIntegration
|
3
3
|
module Matchers
|
4
4
|
##
|
5
|
-
# This
|
5
|
+
# This helper method recursively compares nested Ruby Hashes and Arrays while ignoring
|
6
6
|
# the order of elements in Arrays.
|
7
7
|
module DeepEq
|
8
|
-
|
9
|
-
|
10
|
-
matcher(:deep_eq) { |expected| match { |actual| deep_eq?(actual, expected) } }
|
8
|
+
module_function
|
11
9
|
|
12
10
|
def deep_eq?(actual, expected)
|
13
11
|
return arrays_deep_eq?(actual, expected) if expected.is_a?(Array) && actual.is_a?(Array)
|
@@ -20,8 +18,8 @@ module RSpec
|
|
20
18
|
def arrays_deep_eq?(actual, expected)
|
21
19
|
expected = expected.clone
|
22
20
|
|
23
|
-
actual.each do |
|
24
|
-
index = expected.find_index { |
|
21
|
+
actual.each do |actual_array|
|
22
|
+
index = expected.find_index { |expected_array| deep_eq?(actual_array, expected_array) }
|
25
23
|
return false if index.nil?
|
26
24
|
|
27
25
|
expected.delete_at(index)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "json"
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module GraphqlIntegration
|
3
5
|
module Matchers
|
@@ -7,104 +9,239 @@ module RSpec
|
|
7
9
|
extend RSpec::Matchers::DSL
|
8
10
|
|
9
11
|
##
|
10
|
-
# This error is
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(variable_name, example_value)
|
12
|
+
# This error is raised when the schema class is not set in the RSpec configuration.
|
13
|
+
class SchemaNotSetError < StandardError
|
14
|
+
def initialize
|
14
15
|
super <<~TEXT
|
15
|
-
|
16
|
+
Please define
|
17
|
+
|
18
|
+
config.graphql_schema_class
|
16
19
|
|
17
|
-
|
18
|
-
let(:#{variable_name}) { #{example_value} }
|
20
|
+
in your spec_helper.rb
|
19
21
|
TEXT
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
##
|
24
|
-
#
|
25
|
-
# the
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
# This error is thrown if neither the default request file is present nor
|
27
|
+
# the request_file_overwrite variable is set in a test.
|
28
|
+
class DefaultRequestFileMissing < StandardError
|
29
|
+
def initialize(default_request_file)
|
30
|
+
super <<~TEXT
|
31
|
+
No default request file found for this test.
|
32
|
+
|
33
|
+
Please create either a default request file:
|
34
|
+
#{default_request_file}
|
35
|
+
|
36
|
+
or define a file with the request_file_overwrite variable:
|
37
|
+
let(:request_file_overwrite) { File.join(File.dirname(__FILE__), "my_request_file.graphql") }
|
38
|
+
TEXT
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# This error is thrown if neither the default request file is present nor
|
44
|
+
# the response_file_overwrite variable is set in a test.
|
45
|
+
class DefaultResponseFileMissing < StandardError
|
46
|
+
def initialize(default_response_file)
|
47
|
+
super <<~TEXT
|
48
|
+
No default response file found for this test.
|
49
|
+
|
50
|
+
Please create either a default response file:
|
51
|
+
#{default_response_file}
|
52
|
+
|
53
|
+
or define a file with the response_file_overwrite variable:
|
54
|
+
let(:response_file_overwrite) { File.join(File.dirname(__FILE__), "my_response_file.graphql") }
|
55
|
+
TEXT
|
56
|
+
end
|
57
|
+
end
|
29
58
|
|
30
59
|
matcher(:match_graphql_response) do |_expected| # rubocop:disable Metrics/BlockLength
|
31
60
|
match do |_actual|
|
32
|
-
|
61
|
+
# expected_response needs to be loaded first because it might contain variables
|
62
|
+
# that are required in the request and that aren't loaded yet. Such variables
|
63
|
+
# could be database objects that could be created while loading the response.
|
64
|
+
expected_response
|
33
65
|
|
34
|
-
# We need to test the responses with
|
66
|
+
# We need to test the responses with DeepEq so that we ignore
|
35
67
|
# the order in nested hashes.
|
36
|
-
|
37
|
-
rescue RSpec::Expectations::ExpectationNotMetError => e
|
38
|
-
@error = e
|
39
|
-
raise
|
68
|
+
DeepEq.deep_eq?(actual_response, expected_response)
|
40
69
|
end
|
41
70
|
|
42
71
|
# For the failure message, we want to show the diff between the actual and
|
43
72
|
# the expected response and the standard eq matcher from RSpec does that best.
|
44
73
|
failure_message { expect(actual_response).to eq(expected_response) }
|
45
74
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
75
|
+
##
|
76
|
+
# Loads the response file and substitutes the variables in the response file.
|
77
|
+
def expected_response
|
78
|
+
@expected_response ||=
|
79
|
+
begin
|
80
|
+
expected_response =
|
81
|
+
load_response(
|
82
|
+
response_file,
|
83
|
+
defined?(response_variables) ? response_variables : {},
|
84
|
+
)
|
85
|
+
|
86
|
+
expected_response = [expected_response] unless expected_response.is_a?(Array)
|
87
|
+
|
88
|
+
expected_response
|
50
89
|
end
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Executes the query with the context and the variables against the schema and
|
94
|
+
# returns the response.
|
95
|
+
def actual_response
|
96
|
+
@actual_response ||=
|
97
|
+
begin
|
98
|
+
response =
|
99
|
+
schema_class.execute(
|
100
|
+
File.read(request_file),
|
101
|
+
context: defined?(context) ? context : {},
|
102
|
+
variables: defined?(request_variables) ? request_variables : {},
|
103
|
+
)
|
104
|
+
|
105
|
+
response.values
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# This method tries to get the file path for the file that is running the tests.
|
111
|
+
#
|
112
|
+
# The magic of this method can be overwritten by defining:
|
113
|
+
# let(:test_file_overwrite) { __FILE__ }
|
114
|
+
def test_file
|
115
|
+
return test_file_overwrite if defined?(test_file_overwrite)
|
116
|
+
|
117
|
+
caller_location =
|
118
|
+
caller_locations.find { |location| location.path.include?("/spec/graphql") }
|
119
|
+
|
120
|
+
caller_location.path
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# This method defines the folder where the request and response files are stored.
|
125
|
+
#
|
126
|
+
# It's either the folder of the file that is running the tests or a subfolder
|
127
|
+
# named like the test file.
|
128
|
+
def files_folder
|
129
|
+
if RSpec.configuration.graphql_put_files_in_folder
|
130
|
+
test_file.gsub("_spec.rb", "")
|
131
|
+
else
|
132
|
+
File.dirname(test_file)
|
51
133
|
end
|
52
134
|
end
|
53
135
|
|
54
|
-
|
55
|
-
|
136
|
+
##
|
137
|
+
# This method tries to get the file path for the request file.
|
138
|
+
#
|
139
|
+
# If the request_file_overwrite variable is set, it uses that.
|
140
|
+
#
|
141
|
+
# raises DefaultRequestFileMissing if no request file is found.
|
142
|
+
def request_file
|
143
|
+
if defined?(request_file_overwrite)
|
144
|
+
return File.join(files_folder, request_file_overwrite)
|
145
|
+
end
|
56
146
|
|
57
|
-
|
147
|
+
default_request_file = File.join(files_folder, default_request_file_name)
|
58
148
|
|
59
|
-
|
149
|
+
unless File.exist?(default_request_file)
|
150
|
+
raise DefaultRequestFileMissing, default_request_file
|
151
|
+
end
|
152
|
+
|
153
|
+
default_request_file
|
60
154
|
end
|
61
155
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
156
|
+
##
|
157
|
+
# The default request file is either called like the test file without _spec
|
158
|
+
# but with .graphql or it's in the subfolder of the test file called "request.graphql".
|
159
|
+
def default_request_file_name
|
160
|
+
if RSpec.configuration.graphql_put_files_in_folder
|
161
|
+
"request.graphql"
|
162
|
+
else
|
163
|
+
test_file.split("/").last.gsub("_spec.rb", ".graphql")
|
164
|
+
end
|
71
165
|
end
|
72
166
|
|
167
|
+
##
|
168
|
+
# This method tries to get the file path for the response file.
|
169
|
+
#
|
170
|
+
# If the response_file_overwrite variable is set, it uses that.
|
171
|
+
#
|
172
|
+
# raises DefaultRequestFileMissing if no response file is found.
|
173
|
+
def response_file
|
174
|
+
if defined?(response_file_overwrite)
|
175
|
+
return File.join(files_folder, response_file_overwrite)
|
176
|
+
end
|
177
|
+
|
178
|
+
default_response_file = File.join(files_folder, default_response_file_name)
|
179
|
+
|
180
|
+
unless File.exist?(default_response_file)
|
181
|
+
raise DefaultResponseFileMissing, default_response_file
|
182
|
+
end
|
183
|
+
|
184
|
+
default_response_file
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# The default response file is either called like the test file without _spec
|
189
|
+
# but with .json or it's in the subfolder of the test file called "response.json".
|
190
|
+
def default_response_file_name
|
191
|
+
if RSpec.configuration.graphql_put_files_in_folder
|
192
|
+
"response.json"
|
193
|
+
else
|
194
|
+
test_file.split("/").last.gsub("_spec.rb", ".json")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# This method gets the schema class from the RSpec configuration.
|
200
|
+
#
|
201
|
+
# If schema_class_overwrite is set, it uses that.
|
202
|
+
#
|
203
|
+
# raises SchemaNotSetError if the schema class is not set.
|
73
204
|
def schema_class
|
74
205
|
# It's possible to overwrite the schema class if an app has multiple schemas.
|
75
206
|
return schema_class_overwrite if defined?(schema_class_overwrite)
|
76
207
|
|
77
|
-
if RSpec.configuration.graphql_schema_class.nil?
|
78
|
-
raise "Please define config.graphql_schema_class in your rails_helper.rb"
|
79
|
-
end
|
208
|
+
raise SchemaNotSetError if RSpec.configuration.graphql_schema_class.nil?
|
80
209
|
|
81
210
|
RSpec.configuration.graphql_schema_class
|
82
211
|
end
|
83
212
|
end
|
84
213
|
|
85
|
-
##
|
86
|
-
# Loads a query in a GraphQL file.
|
87
|
-
#
|
88
|
-
# Example:
|
89
|
-
# load_query(__FILE__, 'current_user/query.graphql'),
|
90
|
-
def load_query(dir, filename)
|
91
|
-
File.read(File.join(File.dirname(dir), filename))
|
92
|
-
end
|
93
|
-
|
94
214
|
##
|
95
215
|
# Loads a response in a JSON file and substitute the passed variables that
|
96
216
|
# are surrounded by {{...}} in the file.
|
97
217
|
#
|
98
218
|
# Example:
|
99
219
|
# load_response(
|
100
|
-
#
|
101
|
-
# 'current_user/response.json',
|
220
|
+
# "current_user.json",
|
102
221
|
# {
|
103
|
-
# user_id:
|
222
|
+
# user_id: 1,
|
104
223
|
# },
|
105
224
|
# )
|
106
|
-
|
107
|
-
|
225
|
+
#
|
226
|
+
# current_user.json:
|
227
|
+
# {
|
228
|
+
# "data": {
|
229
|
+
# "currentUser": {
|
230
|
+
# "id": "{{user_id}}",
|
231
|
+
# }
|
232
|
+
# }
|
233
|
+
# }
|
234
|
+
#
|
235
|
+
# Result:
|
236
|
+
# {
|
237
|
+
# "data": {
|
238
|
+
# "currentUser": {
|
239
|
+
# "id": "1",
|
240
|
+
# }
|
241
|
+
# }
|
242
|
+
# }
|
243
|
+
def load_response(filename, variables = {})
|
244
|
+
json_file = File.read(filename)
|
108
245
|
variables.each { |key, value| json_file.gsub!("\"{{#{key}}}\"", JSON.dump(value)) }
|
109
246
|
|
110
247
|
JSON.parse(json_file)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-graphql-integration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Gundel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: prettier
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,48 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
55
111
|
- !ruby/object:Gem::Dependency
|
56
112
|
name: rubocop
|
57
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +122,34 @@ dependencies:
|
|
66
122
|
- - ">="
|
67
123
|
- !ruby/object:Gem::Version
|
68
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
69
153
|
description:
|
70
154
|
email:
|
71
155
|
- gundel.peter@gmail.com
|
@@ -91,14 +175,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
175
|
requirements:
|
92
176
|
- - ">="
|
93
177
|
- !ruby/object:Gem::Version
|
94
|
-
version: '2.
|
178
|
+
version: '2.7'
|
95
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
180
|
requirements:
|
97
181
|
- - ">="
|
98
182
|
- !ruby/object:Gem::Version
|
99
183
|
version: '0'
|
100
184
|
requirements: []
|
101
|
-
rubygems_version: 3.
|
185
|
+
rubygems_version: 3.1.6
|
102
186
|
signing_key:
|
103
187
|
specification_version: 4
|
104
188
|
summary: An RSpec plugin to simplify integration tests for GraphQL
|