Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a pretty debug implementation to overcome escaping of strings #519

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion graphql_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub trait GraphQLQuery {
}

/// The form in which queries are sent over HTTP in most implementations. This will be built using the [`GraphQLQuery`] trait normally.
#[derive(Debug, Serialize, Deserialize)]
#[derive(Serialize, Deserialize)]
pub struct QueryBody<Variables> {
/// The values for the variables. They must match those declared in the queries. This should be the `Variables` struct from the generated module corresponding to the query.
pub variables: Variables,
Expand All @@ -100,6 +100,28 @@ pub struct QueryBody<Variables> {
pub operation_name: &'static str,
}

struct PrettyStr<'a>(&'a str);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct should be named after its goal: ExpandNewLines


impl<'a> fmt::Debug for PrettyStr<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Use `{}` (Display) instead of `{:?}` (Debug) to avoid escaping newlines.
write!(f, "\"{}\"", self.0)
}
}

impl<Variables: fmt::Debug> fmt::Debug for QueryBody<Variables> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("QueryBody")
.field("variables", &self.variables)
// Replace the escaped literal "\n" with actual newline characters.
// This is necessary because when using code-generation,
// multi-line strings in macros are escaped and become a single
// line string in the generated code
.field("query", &PrettyStr(self.query))
.field("operation_name", &self.operation_name)
.finish()
}
}
/// Represents a location inside a query string. Used in errors. See [`Error`].
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Location {
Expand Down
40 changes: 40 additions & 0 deletions graphql_client/tests/readable_debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use graphql_client::*;
use opt_query::Param;

#[derive(GraphQLQuery)]
#[graphql(
query_path = "tests/default/query.graphql",
schema_path = "tests/default/schema.graphql",
variables_derives = "Default, Debug"
)]
struct OptQuery;

fn normalize_whitespace(s: &str) -> String {
s.lines()
.map(str::trim)
.filter(|line| !line.is_empty())
.collect::<Vec<_>>()
.join("\n")
}

#[test]
fn query_is_formatted_correctly() {
let variables = opt_query::Variables {
param: Some(Param::AUTHOR),
};
let query = OptQuery::build_query(variables);
let debug_output = format!("{:#?}", query);

let original_query = include_str!("default/query.graphql");

// Normalize both for comparison
let normalized_debug_output = normalize_whitespace(&debug_output);
let normalized_original_query = normalize_whitespace(original_query);

assert!(
normalized_debug_output.contains(&normalized_original_query),
"Debug output did not contain the expected query.\nDebug output:\n{}\n\nExpected query:\n{}",
normalized_debug_output,
normalized_original_query
);
}
Comment on lines +21 to +40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an outsider, it is not clear what is actually tested here. You try to test something about newlines, but that is not mentioned in this test.