rspec-graphql_response 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +13 -4
- data/README.md +33 -29
- data/RELEASE_NOTES.md +23 -12
- data/UPGRADE.md +5 -1
- data/docs/add_helper.md +4 -5
- data/docs/execute_graphql.md +16 -9
- data/docs/{have_operation.md → have_field.md} +5 -5
- data/docs/operation.md +1 -36
- data/docs/response.md +1 -1
- data/docs/response_data.md +146 -0
- data/lib/rspec/graphql_response.rb +1 -0
- data/lib/rspec/graphql_response/dig_dug/dig_dug.rb +83 -0
- data/lib/rspec/graphql_response/helpers.rb +8 -6
- data/lib/rspec/graphql_response/helpers/execute_graphql.rb +11 -6
- data/lib/rspec/graphql_response/helpers/graphql_context.rb +1 -1
- data/lib/rspec/graphql_response/helpers/graphql_operation.rb +3 -0
- data/lib/rspec/graphql_response/helpers/graphql_variables.rb +1 -1
- data/lib/rspec/graphql_response/helpers/response_data.rb +13 -0
- data/lib/rspec/graphql_response/matchers.rb +1 -1
- data/lib/rspec/graphql_response/matchers/{have_operation.rb → have_field.rb} +3 -3
- data/lib/rspec/graphql_response/validators.rb +1 -1
- data/lib/rspec/graphql_response/validators/{have_operation.rb → have_field.rb} +1 -1
- data/lib/rspec/graphql_response/version.rb +1 -1
- data/rspec-graphql_response.gemspec +3 -2
- metadata +41 -25
- data/lib/rspec/graphql_response/helpers/graphql_query.rb +0 -3
- data/lib/rspec/graphql_response/helpers/operation.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7104f657d559b5617486876024bc92367f177b94734ac8f224452cf6e4917f3e
|
4
|
+
data.tar.gz: f9c0df4206c1dd6c02f7b744b5edaa91c877a2e0be5c1ee235d6a05e0c3df9f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71ef7903cb4b46d5588b03402a5c3e44d6c61e13b898f8269f44ec3acd3b976cd3c77f921b68fc050dab0a20700f5846007c79cacfef8acfe1516f6af1a2045d
|
7
|
+
data.tar.gz: e9bbad747532e9fca29ed6e0bf8b4299be8896344f9541527bff4f71242ecfe4117f02d9946d0aece0215ec1952ce391bb5bfe74eccce747c167da52fe06acb2
|
data/Gemfile.lock
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rspec-graphql_response (0.
|
5
|
-
|
4
|
+
rspec-graphql_response (0.5.0)
|
5
|
+
graphql (>= 1.0)
|
6
|
+
rspec (>= 3.0)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
attr_extras (6.2.4)
|
10
12
|
byebug (11.1.3)
|
11
13
|
coderay (1.1.3)
|
12
14
|
diff-lcs (1.4.4)
|
13
|
-
graphql (1.12.
|
15
|
+
graphql (1.12.6)
|
14
16
|
method_source (1.0.0)
|
17
|
+
optimist (3.0.1)
|
18
|
+
patience_diff (1.2.0)
|
19
|
+
optimist (~> 3.0)
|
15
20
|
pry (0.14.0)
|
16
21
|
coderay (~> 1.1)
|
17
22
|
method_source (~> 1.0)
|
@@ -32,17 +37,21 @@ GEM
|
|
32
37
|
diff-lcs (>= 1.2.0, < 2.0)
|
33
38
|
rspec-support (~> 3.10.0)
|
34
39
|
rspec-support (3.10.2)
|
40
|
+
super_diff (0.6.1)
|
41
|
+
attr_extras (>= 6.2.4)
|
42
|
+
diff-lcs
|
43
|
+
patience_diff
|
35
44
|
|
36
45
|
PLATFORMS
|
37
46
|
ruby
|
38
47
|
|
39
48
|
DEPENDENCIES
|
40
49
|
bundler (~> 1.17)
|
41
|
-
graphql (~> 1.12)
|
42
50
|
pry (~> 0.14)
|
43
51
|
pry-byebug (~> 3.8)
|
44
52
|
rake (>= 12.0)
|
45
53
|
rspec-graphql_response!
|
54
|
+
super_diff (~> 0.6)
|
46
55
|
|
47
56
|
BUNDLED WITH
|
48
57
|
1.17.2
|
data/README.md
CHANGED
@@ -30,40 +30,45 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
## Full Documentation
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
- [Release Notes](/RELEASE_NOTES.md)
|
34
|
+
- [Upgrade Guide](/UPGRADE.md)
|
35
35
|
|
36
36
|
The full documentation for RSpec::GraphQLResponse can be found in the `/docs` folder.
|
37
37
|
|
38
38
|
Configuration:
|
39
|
-
|
40
|
-
|
39
|
+
|
40
|
+
- [RSpec::GraphQLResponse.configure](/docs/configuration.md)
|
41
|
+
- [Spec Type :graphql](/docs/graphql_spec_type.md)
|
41
42
|
|
42
43
|
Custom Matchers:
|
43
|
-
|
44
|
-
|
44
|
+
|
45
|
+
- [have_errors](/docs/have_errors.md) - validates errors, or lack of, on the GraphQL response
|
46
|
+
- [have_field](/docs/have_field.md) - validates the presence of a specified graphql operation in the graphql response
|
45
47
|
|
46
48
|
Context / Describe Helper Methods:
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
|
50
|
+
- [graphql_operation](/docs/execute_graphql.md) - the operation to execute (i.e query or mutation)
|
51
|
+
- [graphql_variables](/docs/execute_graphql.md) - a hash of variables the query expects
|
52
|
+
- [graphql_context](/docs/execute_graphql.md) - the `context` of a query or mutation's resolver
|
51
53
|
|
52
54
|
Spec Helper Methods:
|
53
|
-
|
54
|
-
|
55
|
+
|
56
|
+
- [execute_graphql](/docs/execute_graphql.md) - executes a graphql call with the registered schema, query, variables and context
|
57
|
+
- [response](/docs/response.md) - the response, as JSON, of the executed graphql query
|
58
|
+
- [response_data](/docs/response_data.md) - digs through the graphql response to return data from the specified node(s)
|
55
59
|
|
56
60
|
API / Development
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
|
62
|
+
- [.add_matcher](/docs/add_matcher.md) - add a custom RSpec matcher to the GraphQLResponse matchers
|
63
|
+
- [.add_validator](/docs/add_validator.md) - add a custom validator to be used by the custom matchers
|
64
|
+
- [.add_helper](/docs/add_helper.md) - add helper methods to your specs, made avialable in `it` or `describe` / `context` blocks
|
60
65
|
|
61
66
|
## Getting Started
|
62
67
|
|
63
|
-
There are only a couple of bits you need to get started:
|
68
|
+
There are only a couple of bits you need to get started:
|
64
69
|
|
65
|
-
|
66
|
-
|
70
|
+
- configuration of a GraphQL Schema in [`RSpec::GraphQLResponse.configure`](/docs/configuration.md)
|
71
|
+
- the inclusion of [`type: :graphql`](/docs/graphql_spec_type.md) in your `RSpec.describe` call
|
67
72
|
|
68
73
|
```ruby
|
69
74
|
RSpec::GraphQLResponse.configure do |config|
|
@@ -114,7 +119,7 @@ in your specs.
|
|
114
119
|
|
115
120
|
```ruby
|
116
121
|
RSpec.describe Some::Thing, type: :graphql do
|
117
|
-
|
122
|
+
graphql_operation <<-GQL
|
118
123
|
query ListCharacters{
|
119
124
|
characters {
|
120
125
|
id
|
@@ -138,7 +143,7 @@ way. The reduce this, `RSpec::GraphQLResponse` provides a built-in `response` he
|
|
138
143
|
|
139
144
|
```ruby
|
140
145
|
RSpec.describe Some::Thing, type: :graphql do
|
141
|
-
|
146
|
+
graphql_operation <<-GQL
|
142
147
|
query ListCharacters{
|
143
148
|
characters {
|
144
149
|
id
|
@@ -157,15 +162,15 @@ RSpec.describe Some::Thing, type: :graphql do
|
|
157
162
|
end
|
158
163
|
```
|
159
164
|
|
160
|
-
#### Retrieve
|
165
|
+
#### Retrieve response results with `response_data`
|
161
166
|
|
162
167
|
Now that the GraphQL query has been executed and a response has been obtained, it's time to check for the results of a GraphQL
|
163
168
|
operation. In the previous example, the spec is expecting to find `data` with `characters` in the response hash. To reduce the
|
164
|
-
nested hash checking, use the built-in `
|
169
|
+
nested hash checking, use the built-in `response_data` method to retrieve the `characters`:
|
165
170
|
|
166
171
|
```ruby
|
167
172
|
RSpec.describe Some::Thing, type: :graphql do
|
168
|
-
|
173
|
+
graphql_operation <<-GQL
|
169
174
|
query ListCharacters{
|
170
175
|
characters {
|
171
176
|
id
|
@@ -175,18 +180,17 @@ RSpec.describe Some::Thing, type: :graphql do
|
|
175
180
|
GQL
|
176
181
|
|
177
182
|
it "executes the query" do
|
178
|
-
|
179
|
-
|
180
|
-
expect(characters).to include(
|
181
|
-
# ...
|
183
|
+
expect(response_data :characters).to include(
|
184
|
+
# ...
|
182
185
|
)
|
183
186
|
end
|
184
187
|
end
|
185
188
|
```
|
186
189
|
|
187
|
-
Note the lack of `response` use here. Internally, the `
|
190
|
+
Note the lack of `response` use here. Internally, the `response_data` method uses the `response` to obtain the data requested. This
|
188
191
|
means the entire chain of operations from executing the GraphQL request, to converting the response into a hash, and digging
|
189
|
-
through the results to find the correction operation, has been handled behind the scenes.
|
192
|
+
through the results to find the correction operation, has been handled behind the scenes. To see more examples of how to use
|
193
|
+
`response_data` dig through your response check out it's full documenation [here.](/docs/response_data.md)
|
190
194
|
|
191
195
|
## Development
|
192
196
|
|
data/RELEASE_NOTES.md
CHANGED
@@ -4,6 +4,17 @@ Release notes for various versions of RSpec::GraphQLResponse
|
|
4
4
|
|
5
5
|
See [the upgrade guide](/UPGRADE.md) for details on changes between versions and how to upgrade.
|
6
6
|
|
7
|
+
## v0.5.0 - Helper API change
|
8
|
+
|
9
|
+
- Fully deprecates `operation`.
|
10
|
+
- Renames `have_operation` to `have_field` to clarify its use.
|
11
|
+
|
12
|
+
## v0.4.0 - Helper API change
|
13
|
+
|
14
|
+
### Breaking Changes
|
15
|
+
|
16
|
+
The helper `graphql_query` was renamed to `graphql_operation` to better communicate the use of the helper. Naming the helper with `_query` lead to an association that its use was meant for GraphQL query operations and could not also be used for a mutation.
|
17
|
+
|
7
18
|
## v0.2.0 - GraphQL Configuration DSL and Refactorings
|
8
19
|
|
9
20
|
Misc changes and corrections, some new features, and generally trying to create a more robust
|
@@ -11,13 +22,13 @@ and usable experience, right out of the box.
|
|
11
22
|
|
12
23
|
### New Features
|
13
24
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
25
|
+
- Significantly improved documentation
|
26
|
+
- `have_operation` matcher
|
27
|
+
- GraphQL configuration DSL
|
28
|
+
- `graphql_query`
|
29
|
+
- `graphql_variables`
|
30
|
+
- `graphql_context`
|
31
|
+
- Describe/Context level RSpec helper methods via `.add_context_helper` DSL
|
21
32
|
|
22
33
|
### Breaking Changes
|
23
34
|
|
@@ -32,8 +43,8 @@ Lots of misc bug fixes, including caching of values, ensuring things work in nes
|
|
32
43
|
|
33
44
|
Early beta work to get this out the door and begin adoption
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
46
|
+
- `have_errors` matcher
|
47
|
+
- `operation` helper
|
48
|
+
- `response` helper
|
49
|
+
- `execute_graphql` helper
|
50
|
+
- DSL for adding custom matchers, validators, and helpers
|
data/UPGRADE.md
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# Upgrade Guide
|
2
2
|
|
3
|
+
## v0.3.0 to v0.4.0
|
4
|
+
|
5
|
+
There is a breaking change between v0.3.0 and v0.4.0 where the helper `graphql_query` was renamed to `graphql_operation`. In order to migrate to v0.4.0 all references to `graphql_query` can be replaced with `graphql_operation`.
|
6
|
+
|
3
7
|
## v0.1.0 to v0.2.0
|
4
8
|
|
5
|
-
There is a breaking change between v0.1.0 and v0.2.0 regarding the configuration of graphql queries, variables and context.
|
9
|
+
There is a breaking change between v0.1.0 and v0.2.0 regarding the configuration of graphql queries, variables and context.
|
6
10
|
Previously, you defined these three items with `let` in rspec:
|
7
11
|
|
8
12
|
```ruby
|
data/docs/add_helper.md
CHANGED
@@ -23,7 +23,7 @@ it "does stuff" do
|
|
23
23
|
end
|
24
24
|
```
|
25
25
|
|
26
|
-
It's not a huge difference, but when you consider how well the `operation` method handles `nil` and
|
26
|
+
It's not a huge difference, but when you consider how well the `operation` method handles `nil` and
|
27
27
|
operation results that are not found, it's well worth the few lines of savings.
|
28
28
|
|
29
29
|
There are many other helpers available for your test suites, as well. Be sure to check the full
|
@@ -51,15 +51,14 @@ RSpec::GraphQLResponse.add_helper :operation do |operation_name|
|
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
54
|
-
In this example, the `response` helper is used, which guarantees the graphql has been executed and a response
|
54
|
+
In this example, the `response` helper is used, which guarantees the graphql has been executed and a response
|
55
55
|
is available, assuming there were no exceptions preventing that.
|
56
56
|
|
57
57
|
## Add a Context Helper
|
58
58
|
|
59
59
|
In addition to Spec level helpers, RSpec::GraphQLResponse allows you to add custom helpers at the context
|
60
60
|
level. This means you can add configuration and other bits that can be called outside of an `it` block.
|
61
|
-
The existing `
|
62
|
-
context level helpers.
|
61
|
+
The existing `graphql_operation` and other DSL methods for configuring graphql calls are a great example of context level helpers.
|
63
62
|
|
64
63
|
To create a context helper, call `RSpec::GraphQLResponse.add_context_helper(name, &helper_block)`. The params
|
65
64
|
are the same as `.add_helper`, but the resulting method will be made available in `describe` and `context`
|
@@ -73,7 +72,7 @@ end
|
|
73
72
|
|
74
73
|
In this simple example, a method called `my_setting` is created, and it stores a value in the instance variable
|
75
74
|
`@my_setting`. This takes advantage of RSpec's native ability to handle instance variables in describe and
|
76
|
-
context blocks, allowing the variable to exist withing the hierarchy of objects for a given spec.
|
75
|
+
context blocks, allowing the variable to exist withing the hierarchy of objects for a given spec.
|
77
76
|
|
78
77
|
With that defined, it can be used within a spec:
|
79
78
|
|
data/docs/execute_graphql.md
CHANGED
@@ -5,7 +5,10 @@ methods for configuring the query.
|
|
5
5
|
|
6
6
|
```ruby
|
7
7
|
RSPec.describe Cool::Stuff, type: :graphql do
|
8
|
-
|
8
|
+
let(:user) { create(:graphql_user) }
|
9
|
+
let(:search_name) { "Pet" }
|
10
|
+
|
11
|
+
graphql_operation <<-GQL
|
9
12
|
query SomeThing($name: String) {
|
10
13
|
characters(name: $name) {
|
11
14
|
id
|
@@ -13,14 +16,18 @@ RSPec.describe Cool::Stuff, type: :graphql do
|
|
13
16
|
}
|
14
17
|
}
|
15
18
|
GQL
|
16
|
-
|
17
|
-
graphql_variables {
|
18
|
-
name: "Jam"
|
19
|
-
}
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
graphql_variables do
|
21
|
+
{
|
22
|
+
name: search_name
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
grapql_context do
|
27
|
+
{
|
28
|
+
current_user: user
|
29
|
+
}
|
30
|
+
end
|
24
31
|
|
25
32
|
it "executes and does the thing with the vars and context" do
|
26
33
|
# ... expect things here
|
@@ -30,7 +37,7 @@ end
|
|
30
37
|
|
31
38
|
## Available Configuration Methods
|
32
39
|
|
33
|
-
### `
|
40
|
+
### `graphql_operation`
|
34
41
|
|
35
42
|
A string - most commonly a ruby heredoc - for the graphql query to execute
|
36
43
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Validate a response operation with `
|
1
|
+
# Validate a response operation with `have_field(name)`
|
2
2
|
|
3
3
|
Check for the presence of an operation's results. Useful when you want to ensure an operation exists before
|
4
4
|
retrieving the operation's results.
|
@@ -7,7 +7,7 @@ retrieving the operation's results.
|
|
7
7
|
|
8
8
|
```ruby
|
9
9
|
RSpec.describe My::Characters, type: :graphql do
|
10
|
-
|
10
|
+
graphql_operation <<-GQL
|
11
11
|
query CharacterList {
|
12
12
|
characters {
|
13
13
|
id
|
@@ -18,7 +18,7 @@ RSpec.describe My::Characters, type: :graphql do
|
|
18
18
|
|
19
19
|
it "has the characters" do
|
20
20
|
|
21
|
-
expect(response).to
|
21
|
+
expect(response).to have_field(:characters)
|
22
22
|
|
23
23
|
end
|
24
24
|
end
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
RSpec.describe My::Characters, type: :graphql do
|
31
|
-
|
31
|
+
graphql_operation <<-GQL
|
32
32
|
query CharacterList {
|
33
33
|
characters {
|
34
34
|
id
|
@@ -39,7 +39,7 @@ RSpec.describe My::Characters, type: :graphql do
|
|
39
39
|
|
40
40
|
it "does not have books" do
|
41
41
|
|
42
|
-
expect(response).to_not
|
42
|
+
expect(response).to_not have_field(:books)
|
43
43
|
|
44
44
|
end
|
45
45
|
end
|
data/docs/operation.md
CHANGED
@@ -1,38 +1,3 @@
|
|
1
1
|
# Using the `operation` helper
|
2
2
|
|
3
|
-
|
4
|
-
structure that looks like,
|
5
|
-
|
6
|
-
```ruby
|
7
|
-
{
|
8
|
-
"data" => {
|
9
|
-
operation_name
|
10
|
-
}
|
11
|
-
}
|
12
|
-
```
|
13
|
-
|
14
|
-
## Basic Use
|
15
|
-
|
16
|
-
```ruby
|
17
|
-
it "has characters" do
|
18
|
-
characters = operation(:characters)
|
19
|
-
|
20
|
-
expect(character).to include(
|
21
|
-
{ id: 1, name: "Jam" },
|
22
|
-
# ...
|
23
|
-
)
|
24
|
-
end
|
25
|
-
```
|
26
|
-
|
27
|
-
## Handling Nil
|
28
|
-
|
29
|
-
If there is no `"data"` or no named operation for the name supplied, the
|
30
|
-
`operation` helper will return `nil`
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
it "returns nil if operation doesn't exist" do
|
34
|
-
character = operation(:something_that_does_not_exist)
|
35
|
-
|
36
|
-
expect(operation).to be_nil
|
37
|
-
end
|
38
|
-
```
|
3
|
+
Deprecated. See [response_data](response_data.md) instead.
|
data/docs/response.md
CHANGED
@@ -1 +1 @@
|
|
1
|
-
#
|
1
|
+
# The GraphQL Response, via Helper `response`
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Using the `response_data` Helper
|
2
|
+
|
3
|
+
The `response_data` helper will dig through a graphql response, through
|
4
|
+
the outer hash, into the response data for an operation, and through any
|
5
|
+
and all layers of hash and array.
|
6
|
+
|
7
|
+
## Syntax
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
response_data *[dig_pattern]
|
11
|
+
```
|
12
|
+
|
13
|
+
Data returned via this helper will assume a `"data" => ` key at the root of
|
14
|
+
the `response` object. This root does not need to be specified in the list
|
15
|
+
of attributes for the `dig_pattern`.
|
16
|
+
|
17
|
+
### Params
|
18
|
+
|
19
|
+
* `*[dig_pattern]` - an array of attributes (`:symbol`, `"string"`, or `key: :value` pair) that describes
|
20
|
+
the data structure to dig through, and the final data set to retrieve from the graphql response.
|
21
|
+
|
22
|
+
#### dig_pattern
|
23
|
+
|
24
|
+
Each attribute added to the `dig_pattern` represents an attribute at the given level of the
|
25
|
+
data structure, in numeric order from left to right. The first attribute provides will dig into
|
26
|
+
that attribute at the first level of data (just below the `"data" =>` key). The second attribute
|
27
|
+
will dig through data just below that first level, etc. etc. etc.
|
28
|
+
|
29
|
+
For example, with a data structure as shown below, in "Basic Use", you could specifiy these
|
30
|
+
attributes for the dig pattern:
|
31
|
+
|
32
|
+
* :characters
|
33
|
+
* :name
|
34
|
+
|
35
|
+
Like this:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
response_data :characters, :name
|
39
|
+
```
|
40
|
+
|
41
|
+
This dig pattern will find the `"characters"` key just below `"data"`, then iterate through
|
42
|
+
the array of characters and retrieve the `"name"` of each character.
|
43
|
+
|
44
|
+
For more details and options for the dig pattern, see the examples below.
|
45
|
+
|
46
|
+
## Basic Use
|
47
|
+
|
48
|
+
A `response` data structure may look something like the following.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
{
|
52
|
+
"data" => {
|
53
|
+
"characters" => [
|
54
|
+
{ "id" => "1", "name" => "Jam" },
|
55
|
+
{ "id" => "2", "name" => "Redemption" },
|
56
|
+
{ "id" => "3", "name" => "Pet" }
|
57
|
+
]
|
58
|
+
}
|
59
|
+
}
|
60
|
+
```
|
61
|
+
|
62
|
+
The `response_data` helper will dig through to give you simplified
|
63
|
+
results that are easier to verify.
|
64
|
+
|
65
|
+
For example, if only the names of the characters need to be checked:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
response_data :characters, :name
|
69
|
+
|
70
|
+
# => ["Jam", "Redemption", "Pet"]
|
71
|
+
```
|
72
|
+
|
73
|
+
Or perhaps only the name for 2nd character is needed:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
response_data {characters: [1]}, :name
|
77
|
+
|
78
|
+
# => "Redemption"
|
79
|
+
```
|
80
|
+
|
81
|
+
## List Every Item in an Array
|
82
|
+
|
83
|
+
Many responses from a graphql call will include an array of data somewhere
|
84
|
+
in the data structure. If you need to return all of the items in an array,
|
85
|
+
you only need to specify that array's key:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
it "has characters" do
|
89
|
+
characters = response_data(:characters)
|
90
|
+
|
91
|
+
expect(character).to include(
|
92
|
+
{ id: 1, name: "Jam" },
|
93
|
+
# ...
|
94
|
+
)
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
## Dig a Field From Every Item in an Array
|
99
|
+
|
100
|
+
When validation only needs to occur on a specific field for items found in
|
101
|
+
an array, there are two options.
|
102
|
+
|
103
|
+
1. Specify a list of fields as already shown
|
104
|
+
2. change the array's key to a hash and provide a `:symbol` wrapped in an array as the value
|
105
|
+
|
106
|
+
The first option was already shown in the Basic Use section above.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
response_data :characters, :name
|
110
|
+
|
111
|
+
# => ["Jam", "Redemption", "Pet"]
|
112
|
+
```
|
113
|
+
|
114
|
+
For the second option, the code would look like this:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
response_data characters: [:name]
|
118
|
+
|
119
|
+
# => ["Jam", "Redemption", "Pet"]
|
120
|
+
```
|
121
|
+
|
122
|
+
Both of these options are functionaly the same. The primary difference will be
|
123
|
+
how you wish to express the data structure in your code. Changing the list of
|
124
|
+
attributes to a hash with an array wrapping the value will provide a better
|
125
|
+
indication that an array is expected at that point in the data structure.
|
126
|
+
|
127
|
+
## Dig Out an Item By Index, From an Array
|
128
|
+
|
129
|
+
There may be times when only a single piece of a returned array needs to be
|
130
|
+
validated. To handle this, switch the key of the array to a hash, as in the
|
131
|
+
previous example. Rather than specifying a child node's key in the value, though,
|
132
|
+
specify the index of the item you wish to extract.
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
response_data characters: [1]
|
136
|
+
```
|
137
|
+
|
138
|
+
This will return the character at index 1, from the array of characters.
|
139
|
+
|
140
|
+
## Handling Nil
|
141
|
+
|
142
|
+
If there is no data the key supplied, the helper will return `nil`
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
response_data(:something_that_does_not_exist) #=> nil
|
146
|
+
```
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RSpec
|
2
|
+
module GraphQLResponse
|
3
|
+
class DigDug
|
4
|
+
attr_reader :dig_pattern
|
5
|
+
|
6
|
+
def initialize(*dig_pattern)
|
7
|
+
@dig_pattern = parse_dig_pattern(*dig_pattern)
|
8
|
+
end
|
9
|
+
|
10
|
+
def dig(data)
|
11
|
+
dig_data(data, dig_pattern)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def dig_data(data, patterns)
|
17
|
+
return data if patterns.nil?
|
18
|
+
return data if patterns.empty?
|
19
|
+
|
20
|
+
node = patterns[0]
|
21
|
+
node_key = node[:key]
|
22
|
+
node_key = node_key.to_s if node_key.is_a? Symbol
|
23
|
+
node_value = node[:value]
|
24
|
+
|
25
|
+
if node[:type] == :symbol
|
26
|
+
result = dig_symbol(data, node_key)
|
27
|
+
elsif node[:type] == :array
|
28
|
+
if data.is_a? Hash
|
29
|
+
child_data = data[node_key]
|
30
|
+
result = dig_symbol(child_data, node_value)
|
31
|
+
elsif data.is_a? Array
|
32
|
+
result = data.map { |value|
|
33
|
+
child_data = value[node_key]
|
34
|
+
dig_symbol(child_data, node_value)
|
35
|
+
}.compact
|
36
|
+
else
|
37
|
+
result = data
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
dig_data(result, patterns.drop(1))
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_dig_pattern(*pattern)
|
45
|
+
pattern_config = pattern.map do |pattern_item|
|
46
|
+
if pattern_item.is_a? Symbol
|
47
|
+
{
|
48
|
+
type: :symbol,
|
49
|
+
key: pattern_item
|
50
|
+
}
|
51
|
+
elsif pattern_item.is_a? Hash
|
52
|
+
pattern_item.map do |key, value|
|
53
|
+
{
|
54
|
+
type: :array,
|
55
|
+
key: key,
|
56
|
+
value: value[0]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
pattern_config.flatten
|
63
|
+
end
|
64
|
+
|
65
|
+
def dig_symbol(data, key)
|
66
|
+
key = key.to_s if key.is_a? Symbol
|
67
|
+
return data[key] if data.is_a? Hash
|
68
|
+
|
69
|
+
if data.is_a? Array
|
70
|
+
if key.is_a? Numeric
|
71
|
+
mapped_data = data[key]
|
72
|
+
else
|
73
|
+
mapped_data = data.map { |value| value[key] }.flatten
|
74
|
+
end
|
75
|
+
|
76
|
+
return mapped_data
|
77
|
+
end
|
78
|
+
|
79
|
+
return data
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -6,13 +6,14 @@ module RSpec
|
|
6
6
|
|
7
7
|
def self.add_helper(name, scope: :spec, &helper)
|
8
8
|
helper_module = Module.new do |mod|
|
9
|
-
mod.define_method(name) do |*args|
|
9
|
+
mod.define_method(name) do |*args, &block|
|
10
10
|
instance_var = "@#{name}".to_sym
|
11
11
|
|
12
12
|
if self.instance_variables.include? instance_var
|
13
13
|
return self.instance_variable_get(instance_var)
|
14
14
|
end
|
15
15
|
|
16
|
+
args << block
|
16
17
|
result = self.instance_exec(*args, &helper)
|
17
18
|
self.instance_variable_set(instance_var, result)
|
18
19
|
end
|
@@ -20,7 +21,8 @@ module RSpec
|
|
20
21
|
|
21
22
|
RSpec.configure do |config|
|
22
23
|
config.after(:each) do
|
23
|
-
|
24
|
+
instance_var = "@#{name}".to_sym
|
25
|
+
helper_module.instance_variable_set(instance_var, nil)
|
24
26
|
end
|
25
27
|
|
26
28
|
module_method = if scope == :spec
|
@@ -38,11 +40,11 @@ module RSpec
|
|
38
40
|
end
|
39
41
|
|
40
42
|
# describe level helpers
|
41
|
-
require_relative "helpers/graphql_query"
|
42
|
-
require_relative "helpers/graphql_variables"
|
43
43
|
require_relative "helpers/graphql_context"
|
44
|
+
require_relative "helpers/graphql_operation"
|
45
|
+
require_relative "helpers/graphql_variables"
|
44
46
|
|
45
47
|
# spec level helpers
|
46
|
-
require_relative "helpers/operation"
|
47
|
-
require_relative "helpers/response"
|
48
48
|
require_relative "helpers/execute_graphql"
|
49
|
+
require_relative "helpers/response"
|
50
|
+
require_relative "helpers/response_data"
|
@@ -1,12 +1,17 @@
|
|
1
1
|
RSpec::GraphQLResponse.add_helper :execute_graphql do
|
2
2
|
config = RSpec::GraphQLResponse.configuration
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
query_context = get_graphql_context if respond_to? :get_graphql_context
|
4
|
+
operation = graphql_operation if respond_to? :graphql_operation
|
5
|
+
operation = self.instance_eval(&graphql_operation) if operation.is_a? Proc
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
operation_vars = graphql_variables if respond_to? :graphql_variables
|
8
|
+
operation_vars = self.instance_eval(&graphql_variables) if operation_vars.is_a? Proc
|
9
|
+
|
10
|
+
operation_context = graphql_context if respond_to? :graphql_context
|
11
|
+
operation_context = self.instance_eval(&operation_context) if operation_context.is_a? Proc
|
12
|
+
|
13
|
+
config.graphql_schema.execute(operation, {
|
14
|
+
variables: operation_vars,
|
15
|
+
context: operation_context
|
11
16
|
})
|
12
17
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
RSpec::GraphQLResponse.add_helper :response_data do |*fields|
|
2
|
+
next nil unless response.is_a? Hash
|
3
|
+
|
4
|
+
response_data = response["data"]
|
5
|
+
next nil if response_data.nil?
|
6
|
+
next nil if response_data.empty?
|
7
|
+
|
8
|
+
fields = fields.compact
|
9
|
+
next response_data if fields.empty?
|
10
|
+
|
11
|
+
dig_dug = RSpec::GraphQLResponse::DigDug.new(*fields)
|
12
|
+
dig_dug.dig(response_data)
|
13
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
RSpec::GraphQLResponse.add_matcher :
|
1
|
+
RSpec::GraphQLResponse.add_matcher :have_field do |operation_name|
|
2
2
|
match do |response|
|
3
|
-
validator = RSpec::GraphQLResponse.validator(:
|
3
|
+
validator = RSpec::GraphQLResponse.validator(:have_field)
|
4
4
|
|
5
5
|
@result = validator.validate(response, operation_name: operation_name)
|
6
6
|
@result.valid?
|
@@ -11,7 +11,7 @@ RSpec::GraphQLResponse.add_matcher :have_operation do |operation_name|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
match_when_negated do |response|
|
14
|
-
validator = RSpec::GraphQLResponse.validator(:
|
14
|
+
validator = RSpec::GraphQLResponse.validator(:have_field)
|
15
15
|
|
16
16
|
@result = validator.validate_negated(response, operation_name: operation_name)
|
17
17
|
@result.valid?
|
@@ -1,4 +1,4 @@
|
|
1
|
-
RSpec::GraphQLResponse.add_validator :
|
1
|
+
RSpec::GraphQLResponse.add_validator :have_field do
|
2
2
|
failure_message :nil, "Cannot evaluate operations on nil"
|
3
3
|
failure_message :not_found, ->(expected, actual) { "Expected to find operation result named #{expected}, but did not find it\n\t#{actual}" }
|
4
4
|
|
@@ -26,10 +26,11 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
28
|
spec.add_development_dependency "bundler", "~> 1.17"
|
29
|
-
spec.add_development_dependency "graphql", "~> 1.12"
|
30
29
|
spec.add_development_dependency "rake", ">= 12.0"
|
31
30
|
spec.add_development_dependency "pry", "~> 0.14"
|
32
31
|
spec.add_development_dependency "pry-byebug", "~> 3.8"
|
32
|
+
spec.add_development_dependency "super_diff", "~> 0.6"
|
33
33
|
|
34
|
-
spec.add_runtime_dependency "rspec", "
|
34
|
+
spec.add_runtime_dependency "rspec", ">= 3.0"
|
35
|
+
spec.add_runtime_dependency "graphql", ">= 1.0"
|
35
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-graphql_response
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- River Lynn Bailey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.17'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: graphql
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.12'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.12'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,19 +67,47 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '3.8'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: super_diff
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
type: :
|
75
|
+
version: '0.6'
|
76
|
+
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
82
|
+
version: '0.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: graphql
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.0'
|
97
111
|
description: Adds a :graphql rspec type with built-in helpers and matchers for ruby-graphql
|
98
112
|
gem responses
|
99
113
|
email:
|
@@ -126,24 +140,26 @@ files:
|
|
126
140
|
- docs/execute_graphql.md
|
127
141
|
- docs/graphql_spec_type.md
|
128
142
|
- docs/have_errors.md
|
129
|
-
- docs/
|
143
|
+
- docs/have_field.md
|
130
144
|
- docs/operation.md
|
131
145
|
- docs/response.md
|
146
|
+
- docs/response_data.md
|
132
147
|
- lib/rspec/graphql_response.rb
|
133
148
|
- lib/rspec/graphql_response/configuration.rb
|
149
|
+
- lib/rspec/graphql_response/dig_dug/dig_dug.rb
|
134
150
|
- lib/rspec/graphql_response/helpers.rb
|
135
151
|
- lib/rspec/graphql_response/helpers/execute_graphql.rb
|
136
152
|
- lib/rspec/graphql_response/helpers/graphql_context.rb
|
137
|
-
- lib/rspec/graphql_response/helpers/
|
153
|
+
- lib/rspec/graphql_response/helpers/graphql_operation.rb
|
138
154
|
- lib/rspec/graphql_response/helpers/graphql_variables.rb
|
139
|
-
- lib/rspec/graphql_response/helpers/operation.rb
|
140
155
|
- lib/rspec/graphql_response/helpers/response.rb
|
156
|
+
- lib/rspec/graphql_response/helpers/response_data.rb
|
141
157
|
- lib/rspec/graphql_response/matchers.rb
|
142
158
|
- lib/rspec/graphql_response/matchers/have_errors.rb
|
143
|
-
- lib/rspec/graphql_response/matchers/
|
159
|
+
- lib/rspec/graphql_response/matchers/have_field.rb
|
144
160
|
- lib/rspec/graphql_response/validators.rb
|
145
161
|
- lib/rspec/graphql_response/validators/have_errors.rb
|
146
|
-
- lib/rspec/graphql_response/validators/
|
162
|
+
- lib/rspec/graphql_response/validators/have_field.rb
|
147
163
|
- lib/rspec/graphql_response/validators/validation_base.rb
|
148
164
|
- lib/rspec/graphql_response/validators/validation_result.rb
|
149
165
|
- lib/rspec/graphql_response/validators/validation_runner.rb
|