Skip to content

Commit

Permalink
Track directive arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
lanadz-shopify committed Jun 9, 2021
1 parent 7ff5e5b commit cbb9d7c
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ even if you opt to collect them by using `GraphQL::Metrics::Analyzer` and `Graph

# @param metrics [Hash] Directive metrics, including a few details about the directive
# {
# directive_name: "PostDetails",
# directive_name: "customDirective",
# directive_arguments: [
# argument_name: "val",
# argument_value: 10
# ]
# }
def directive_extracted(metrics)
store_metrics(:directives, metrics)
Expand Down
26 changes: 25 additions & 1 deletion lib/graphql/metrics/analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,19 @@ def extract_fields(with_runtime_metrics: true)
end

def on_enter_directive(node, parent, visitor)
directive_extracted({ directive_name: node.name })
arguments = node.arguments.map do |arg|
{
argument_name: arg.name,
argument_value: value_of_node_argument(arg)
}
end

directive_extracted(
{
directive_name: node.name,
directive_arguments: arguments
}
)
end

def result
Expand Down Expand Up @@ -136,6 +148,18 @@ def extract_argument(value, field_defn, parent_input_object = nil)

argument_extracted(static_metrics)
end

def value_of_node_argument(argument)
return nil if argument.nil?

if argument.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
@query.variables[argument.value.name]
elsif argument.value.is_a?(GraphQL::Language::Nodes::Enum)
argument.value.name
else
argument.value
end
end
end
end
end
46 changes: 41 additions & 5 deletions test/unit/graphql/metrics/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,12 @@ def self.parse_error(err, _context)
assert_equal_with_diff_on_failure([], actual_directives)
end

test 'extracts metrics from directives on QUERY location' do
test 'extracts metrics from directives on QUERY and FIELD location' do
context = {}
query = GraphQL::Query.new(
SchemaWithFullMetrics,
query_document_with_directive,
variables: { 'postId': '1', 'titleUpcase': true },
variables: { 'postId': '1', 'titleUpcase': true, 'val': 10 },
operation_name: 'PostDetails',
context: context
)
Expand All @@ -156,7 +156,27 @@ def self.parse_error(err, _context)

actual_directives = results[:directives]

assert_equal_with_diff_on_failure([{ directive_name: "customDirective" }], actual_directives)
assert_equal_with_diff_on_failure(
[
{
directive_name: 'skip',
directive_arguments: [
{
argument_name: 'if',
argument_value: true
},
],
},
{
directive_name: 'customDirective',
directive_arguments: [
{
argument_name: 'val',
argument_value: 10
},
],
},
], actual_directives)
end

test 'extracts metrics from directives on MUTATION location' do
Expand Down Expand Up @@ -188,7 +208,18 @@ def self.parse_error(err, _context)

actual_directives = results[:directives]

assert_equal_with_diff_on_failure([{ directive_name: "customDirective" }], actual_directives)
assert_equal_with_diff_on_failure(
[
{
directive_name: 'customDirective',
directive_arguments: [
{
argument_name: 'val',
argument_value: 10,
},
],
},
], actual_directives)
end

test 'extracts metrics from queries, as well as their fields and arguments (when using Schema.execute)' do
Expand Down Expand Up @@ -1477,11 +1508,16 @@ def kitchen_sink_query_document
end

def query_document_with_directive
# directive applied on query and field location,
# one of directive's value passed as a variable to test
# that argument value is captured correctly

<<~GRAPHQL
query PostDetails($postId: ID!) @customDirective(val: 10) {
query PostDetails($postId: ID!, $val: Int!) @customDirective(val: $val) {
post(id: $postId) {
__typename # Ignored
id
title @skip(if: true)
}
}
GRAPHQL
Expand Down

0 comments on commit cbb9d7c

Please sign in to comment.