Skip to content

Commit b525ada

Browse files
authored
Merge pull request #2471 from graphql-java/escape-multiline-triple-quotes
Escape triple quotes in multiline descriptions correctly
2 parents 6d74414 + 58a6519 commit b525ada

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/main/java/graphql/schema/idl/SchemaPrinter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import java.util.stream.Collectors;
5454
import java.util.stream.Stream;
5555

56+
import static com.google.common.base.Predicates.not;
5657
import static graphql.Directives.DeprecatedDirective;
5758
import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION;
5859
import static graphql.introspection.Introspection.DirectiveLocation.ENUM_VALUE;
@@ -78,6 +79,12 @@ public class SchemaPrinter {
7879
.validLocations(FIELD_DEFINITION, ENUM_VALUE, ARGUMENT_DEFINITION, INPUT_FIELD_DEFINITION)
7980
.build();
8081

82+
/**
83+
* This predicate excludes all directives which are specified bt the GraphQL Specification.
84+
* Printing these directives is optional.
85+
*/
86+
public static final Predicate<GraphQLDirective> ExcludeGraphQLSpecifiedDirectivesPredicate = not(DirectiveInfo::isGraphqlSpecifiedDirective);
87+
8188
/**
8289
* Options to use when printing a schema
8390
*/
@@ -989,7 +996,10 @@ private void printMultiLineHashDescription(PrintWriter out, String prefix, List<
989996

990997
private void printMultiLineDescription(PrintWriter out, String prefix, List<String> lines) {
991998
out.printf("%s\"\"\"\n", prefix);
992-
lines.forEach(l -> out.printf("%s%s\n", prefix, l));
999+
lines.forEach(l -> {
1000+
String escapedTripleQuotes = l.replaceAll("\"\"\"", "\\\\\"\"\"");
1001+
out.printf("%s%s\n", prefix, escapedTripleQuotes);
1002+
});
9931003
out.printf("%s\"\"\"\n", prefix);
9941004
}
9951005

src/test/groovy/graphql/schema/idl/SchemaPrinterTest.groovy

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import static graphql.schema.GraphQLNonNull.nonNull
4242
import static graphql.schema.GraphQLObjectType.newObject
4343
import static graphql.schema.GraphQLScalarType.newScalar
4444
import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring
45+
import static graphql.schema.idl.SchemaPrinter.ExcludeGraphQLSpecifiedDirectivesPredicate
4546
import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions
4647

4748
class SchemaPrinterTest extends Specification {
@@ -75,7 +76,7 @@ class SchemaPrinterTest extends Specification {
7576
throw new UnsupportedOperationException("Not implemented")
7677
}
7778
})
78-
.build()
79+
.build()
7980

8081
def resolver = new TypeResolver() {
8182

@@ -514,7 +515,7 @@ type Query {
514515

515516
def "prints scalar description as comment"() {
516517
given:
517-
GraphQLScalarType myScalar = newScalar().name("Scalar").description( "about scalar").coercing(new Coercing() {
518+
GraphQLScalarType myScalar = newScalar().name("Scalar").description("about scalar").coercing(new Coercing() {
518519
@Override
519520
Object serialize(Object input) {
520521
return null
@@ -530,7 +531,7 @@ type Query {
530531
return null
531532
}
532533
})
533-
.build()
534+
.build()
534535
GraphQLFieldDefinition fieldDefinition = newFieldDefinition()
535536
.name("field").type(myScalar).build()
536537
def queryType = newObject().name("Query").field(fieldDefinition).build()
@@ -1648,7 +1649,7 @@ scalar CustomScalar
16481649
return null
16491650
}
16501651
})
1651-
.build()
1652+
.build()
16521653

16531654
GraphQLFieldDefinition fieldDefinition = newFieldDefinition()
16541655
.name("scalarType").type(myScalar).build()
@@ -1690,7 +1691,7 @@ scalar RandomScalar
16901691
return null
16911692
}
16921693
})
1693-
.build()
1694+
.build()
16941695

16951696
GraphQLFieldDefinition fieldDefinition = newFieldDefinition()
16961697
.name("someType").type(GraphQLInt).build()
@@ -1907,4 +1908,22 @@ type MyQuery {
19071908
result == """directive @foo on FIELD_DEFINITION"""
19081909
}
19091910

1911+
def "description printing escapes triple quotes"() {
1912+
def descriptionWithTripleQuote = 'Hello """ \n World """ """';
1913+
def field = newFieldDefinition().name("hello").type(GraphQLString).build()
1914+
def queryType = newObject().name("Query").field(field).description(descriptionWithTripleQuote).build()
1915+
def schema = GraphQLSchema.newSchema().query(queryType).build()
1916+
when:
1917+
def result = new SchemaPrinter(defaultOptions().includeDirectives(ExcludeGraphQLSpecifiedDirectivesPredicate)).print(schema)
1918+
1919+
then:
1920+
result == '''"""
1921+
Hello \\"""
1922+
World \\""" \\"""
1923+
"""
1924+
type Query {
1925+
hello: String
1926+
}
1927+
'''
1928+
}
19101929
}

0 commit comments

Comments
 (0)