forked from testdouble/rspec-graphql_response
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* wip: start response_data * test: add compact layers - Add superdiff for better diff * update: specs for new proposals * working on new version of response_data to support digging through hash and array for values * core of digging through hash and array are working. still need to get digging specific array index, and shaping from hash keys * digging through an array by index works now * digging by array index and field now work at a basic level * failing spec that shows it can't yet do full nesting of field, hash, array, etc * begin extracting dig_dug to encapsulate the response digging features * first passing spec of first level dig with a hash * core specs to outline the feature set of dig_dug * dig through array to nested fields * dig through an array to return an item by index from the array * handling multiple hash key value sets * additional spec to show indexed item from array that exists within item that came from an array * corrections to hand data as an array or hash * corrected the final spec to show digging through an array, an array by index, then grabbing the name of the items in the final array * using DigDug in response_data * docs for response_data * adding an intro section for syntax, to the response_data docs * bump version to 0.4.1 to prep for release * adjustments to the docs * a missing space * log: add warning of soon to come deprecation Co-authored-by: River Lynn Bailey <[email protected]>
- Loading branch information
1 parent
0ef7c7d
commit d4c4736
Showing
17 changed files
with
536 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,3 @@ | ||
# Using the `operation` helper | ||
|
||
The `operation` helper will dig through a response to find a data | ||
structure that looks like, | ||
|
||
```ruby | ||
{ | ||
"data" => { | ||
operation_name | ||
} | ||
} | ||
``` | ||
|
||
## Basic Use | ||
|
||
```ruby | ||
it "has characters" do | ||
characters = operation(:characters) | ||
|
||
expect(character).to include( | ||
{ id: 1, name: "Jam" }, | ||
# ... | ||
) | ||
end | ||
``` | ||
|
||
## Handling Nil | ||
|
||
If there is no `"data"` or no named operation for the name supplied, the | ||
`operation` helper will return `nil` | ||
|
||
```ruby | ||
it "returns nil if operation doesn't exist" do | ||
character = operation(:something_that_does_not_exist) | ||
|
||
expect(operation).to be_nil | ||
end | ||
``` | ||
Deprecated. See [response_data](response_data.md) instead. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
# Check the GraphQL Response with Helper `response` | ||
# The GraphQL Response, via Helper `response` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Using the `response_data` Helper | ||
|
||
The `response_data` helper will dig through a graphql response, through | ||
the outer hash, into the response data for an operation, and through any | ||
and all layers of hash and array. | ||
|
||
## Syntax | ||
|
||
```ruby | ||
response_data *[dig_pattern] | ||
``` | ||
|
||
Data returned via this helper will assume a `"data" => ` key at the root of | ||
the `response` object. This root does not need to be specified in the list | ||
of attributes for the `dig_pattern`. | ||
|
||
### Params | ||
|
||
* `*[dig_pattern]` - an array of attributes (`:symbol`, `"string"`, or `key: :value` pair) that describes | ||
the data structure to dig through, and the final data set to retrieve from the graphql response. | ||
|
||
#### dig_pattern | ||
|
||
Each attribute added to the `dig_pattern` represents an attribute at the given level of the | ||
data structure, in numeric order from left to right. The first attribute provides will dig into | ||
that attribute at the first level of data (just below the `"data" =>` key). The second attribute | ||
will dig through data just below that first level, etc. etc. etc. | ||
|
||
For example, with a data structure as shown below, in "Basic Use", you could specifiy these | ||
attributes for the dig pattern: | ||
|
||
* :characters | ||
* :name | ||
|
||
Like this: | ||
|
||
```ruby | ||
response_data :characters, :name | ||
``` | ||
|
||
This dig pattern will find the `"characters"` key just below `"data"`, then iterate through | ||
the array of characters and retrieve the `"name"` of each character. | ||
|
||
For more details and options for the dig pattern, see the examples below. | ||
|
||
## Basic Use | ||
|
||
A `response` data structure may look something like the following. | ||
|
||
```ruby | ||
{ | ||
"data" => { | ||
"characters" => [ | ||
{ "id" => "1", "name" => "Jam" }, | ||
{ "id" => "2", "name" => "Redemption" }, | ||
{ "id" => "3", "name" => "Pet" } | ||
] | ||
} | ||
} | ||
``` | ||
|
||
The `response_data` helper will dig through to give you simplified | ||
results that are easier to verify. | ||
|
||
For example, if only the names of the characters need to be checked: | ||
|
||
```ruby | ||
response_data :characters, :name | ||
|
||
# => ["Jam", "Redemption", "Pet"] | ||
``` | ||
|
||
Or perhaps only the name for 2nd character is needed: | ||
|
||
```ruby | ||
response_data {characters: [1]}, :name | ||
|
||
# => "Redemption" | ||
``` | ||
|
||
## List Every Item in an Array | ||
|
||
Many responses from a graphql call will include an array of data somewhere | ||
in the data structure. If you need to return all of the items in an array, | ||
you only need to specify that array's key: | ||
|
||
```ruby | ||
it "has characters" do | ||
characters = response_data(:characters) | ||
|
||
expect(character).to include( | ||
{ id: 1, name: "Jam" }, | ||
# ... | ||
) | ||
end | ||
``` | ||
|
||
## Dig a Field From Every Item in an Array | ||
|
||
When validation only needs to occur on a specific field for items found in | ||
an array, there are two options. | ||
|
||
1. Specify a list of fields as already shown | ||
2. change the array's key to a hash and provide a `:symbol` wrapped in an array as the value | ||
|
||
The first option was already shown in the Basic Use section above. | ||
|
||
```ruby | ||
response_data :characters, :name | ||
|
||
# => ["Jam", "Redemption", "Pet"] | ||
``` | ||
|
||
For the second option, the code would look like this: | ||
|
||
```ruby | ||
response_data characters: [:name] | ||
|
||
# => ["Jam", "Redemption", "Pet"] | ||
``` | ||
|
||
Both of these options are functionaly the same. The primary difference will be | ||
how you wish to express the data structure in your code. Changing the list of | ||
attributes to a hash with an array wrapping the value will provide a better | ||
indication that an array is expected at that point in the data structure. | ||
|
||
## Dig Out an Item By Index, From an Array | ||
|
||
There may be times when only a single piece of a returned array needs to be | ||
validated. To handle this, switch the key of the array to a hash, as in the | ||
previous example. Rather than specifying a child node's key in the value, though, | ||
specify the index of the item you wish to extract. | ||
|
||
```ruby | ||
response_data characters: [1] | ||
``` | ||
|
||
This will return the character at index 1, from the array of characters. | ||
|
||
## Handling Nil | ||
|
||
If there is no data the key supplied, the helper will return `nil` | ||
|
||
```ruby | ||
response_data(:something_that_does_not_exist) #=> nil | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
module RSpec | ||
module GraphQLResponse | ||
class DigDug | ||
attr_reader :dig_pattern | ||
|
||
def initialize(*dig_pattern) | ||
@dig_pattern = parse_dig_pattern(*dig_pattern) | ||
end | ||
|
||
def dig(data) | ||
dig_data(data, dig_pattern) | ||
end | ||
|
||
private | ||
|
||
def dig_data(data, patterns) | ||
return data if patterns.nil? | ||
return data if patterns.empty? | ||
|
||
node = patterns[0] | ||
node_key = node[:key] | ||
node_key = node_key.to_s if node_key.is_a? Symbol | ||
node_value = node[:value] | ||
|
||
if node[:type] == :symbol | ||
result = dig_symbol(data, node_key) | ||
elsif node[:type] == :array | ||
if data.is_a? Hash | ||
child_data = data[node_key] | ||
result = dig_symbol(child_data, node_value) | ||
elsif data.is_a? Array | ||
result = data.map { |value| | ||
child_data = value[node_key] | ||
dig_symbol(child_data, node_value) | ||
}.compact | ||
else | ||
result = data | ||
end | ||
end | ||
|
||
dig_data(result, patterns.drop(1)) | ||
end | ||
|
||
def parse_dig_pattern(*pattern) | ||
pattern_config = pattern.map do |pattern_item| | ||
if pattern_item.is_a? Symbol | ||
{ | ||
type: :symbol, | ||
key: pattern_item | ||
} | ||
elsif pattern_item.is_a? Hash | ||
pattern_item.map do |key, value| | ||
{ | ||
type: :array, | ||
key: key, | ||
value: value[0] | ||
} | ||
end | ||
end | ||
end | ||
|
||
pattern_config.flatten | ||
end | ||
|
||
def dig_symbol(data, key) | ||
key = key.to_s if key.is_a? Symbol | ||
return data[key] if data.is_a? Hash | ||
|
||
if data.is_a? Array | ||
if key.is_a? Numeric | ||
mapped_data = data[key] | ||
else | ||
mapped_data = data.map { |value| value[key] }.flatten | ||
end | ||
|
||
return mapped_data | ||
end | ||
|
||
return data | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
RSpec::GraphQLResponse.add_helper :response_data do |*fields| | ||
next nil unless response.is_a? Hash | ||
|
||
response_data = response["data"] | ||
next nil if response_data.nil? | ||
next nil if response_data.empty? | ||
|
||
fields = fields.compact | ||
next response_data if fields.empty? | ||
|
||
dig_dug = RSpec::GraphQLResponse::DigDug.new(*fields) | ||
dig_dug.dig(response_data) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
module RSpec | ||
module GraphQLResponse | ||
VERSION = "0.4.0" | ||
VERSION = "0.4.1" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.