rspec-graphql_response 0.2.0 → 0.5.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/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
|