Skip to content

Commit

Permalink
fix: Sort arguments by name in SDL
Browse files Browse the repository at this point in the history
`SchemaPrinter` already sorts types and fields by name but similar
sorting for arguments was missing. Arguments in GraphQL are unordered,
so let's make it consistent and a bit more readable.

Also fixes test setups by enforcing unique names for input objects
(cf. #167) and skips checking input objects for null or empty input
fields, as they must have at least one.
  • Loading branch information
stuebingerb committed Jan 30, 2025
1 parent 2dd4d46 commit 99117f0
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ class SchemaPrinter(private val config: SchemaPrinterConfig = SchemaPrinterConfi
// Input Types
// https://spec.graphql.org/draft/#sec-Input-Objects
val inputTypes = buildString {
schemaTypes[TypeKind.INPUT_OBJECT]?.filter { !it.inputFields.isNullOrEmpty() }
?.forEachIndexed { index, type ->
schemaTypes[TypeKind.INPUT_OBJECT]?.forEachIndexed { index, type ->
if (index > 0) {
appendLine()
}
Expand All @@ -184,7 +183,7 @@ class SchemaPrinter(private val config: SchemaPrinterConfig = SchemaPrinterConfi
if (index > 0) {
appendLine()
}
val args = directive.args.takeIf { it.isNotEmpty() }
val args = directive.args.sortedByName().takeIf { it.isNotEmpty() }
?.joinToString(", ", prefix = "(", postfix = ")") { arg ->
arg.name + ": " + arg.type.typeReference() + arg.defaultInfo()
} ?: ""
Expand Down Expand Up @@ -263,15 +262,15 @@ class SchemaPrinter(private val config: SchemaPrinterConfig = SchemaPrinterConfi
// otherwise print them on a single line
if (field.args.any { it.isDeprecated || (config.includeDescriptions && !it.description.isNullOrBlank()) }) {
appendLine("${indentation}${field.name}(")
field.args.forEach { arg ->
field.args.sortedByName().forEach { arg ->
val argsIndentation = "$indentation$indentation"
appendDescription(arg, argsIndentation)
appendLine("$argsIndentation${arg.name}: ${arg.type.typeReference()}${arg.defaultInfo()}${arg.deprecationInfo()}")
}
appendLine("${indentation}): ${field.type.typeReference()}${field.deprecationInfo()}")
} else {
val args =
field.args.takeIf { it.isNotEmpty() }?.joinToString(", ", prefix = "(", postfix = ")") { arg ->
val args = field.args.sortedByName().takeIf { it.isNotEmpty() }
?.joinToString(", ", prefix = "(", postfix = ")") { arg ->
arg.name + ": " + arg.type.typeReference() + arg.defaultInfo()
} ?: ""
appendLine("${indentation}${field.name}$args: ${field.type.typeReference()}${field.deprecationInfo()}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ sealed class TypeNode(override val loc: Location?) : ASTNode() {

class NonNullTypeNode(loc: Location?, val type: TypeNode) : TypeNode(loc)


val isNullable get() = this !is NonNullTypeNode

val isList get() = this is ListTypeNode || (this is NonNullTypeNode && type is ListTypeNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class SchemaPrinterTest {
returnType = linked
nullable = true
description = "link to pdf representation of scenario"
resolver { scenario: Scenario -> null }
resolver { null }
}
}
}
Expand Down Expand Up @@ -163,20 +163,20 @@ class SchemaPrinterTest {
}

sealed class Child
data class Child1(val one: String): Child()
data class Child2(val two: String?): Child()
data class Child1(val one: String) : Child()
data class Child2(val two: String?) : Child()

@Test
fun `schema with union types out of sealed classes should be printed as expected`() {
val schema = KGraphQL.schema {
query("child") {
resolver<Child> { -> Child1("one") }
resolver<Child> { Child1("one") }
}
query("childs") {
resolver<List<Child>> { -> listOf(Child2("one")) }
resolver<List<Child>> { listOf(Child2("one")) }
}
query("nullchilds") {
resolver<List<Child?>?> { -> null }
resolver<List<Child?>?> { null }
}
}

Expand Down Expand Up @@ -367,7 +367,7 @@ class SchemaPrinterTest {
getNullString: String
getObject(nullObject: Boolean!): TestObject
getString: String!
randomInt(min: Int!, max: Int): Int!
randomInt(max: Int, min: Int!): Int!
randomString(possibleReturns: [String!]!): String!
}
Expand Down Expand Up @@ -460,7 +460,7 @@ class SchemaPrinterTest {
type Query {
getStringsForTypes(types: [TestEnum!] = [TYPE1, TYPE2]): [String!]!
getStringWithDefault(type: TestEnum! = TYPE1, string: String!): String!
getStringWithDefault(string: String!, type: TestEnum! = TYPE1): String!
}
enum TestEnum {
Expand Down Expand Up @@ -493,6 +493,7 @@ class SchemaPrinterTest {
}
}
query("data") {
@Suppress("UNUSED_ANONYMOUS_PARAMETER")
resolver { oldOptional: String?, new: String -> "" }.withArgs {
arg(String::class, typeOf<String?>()) {
name = "oldOptional"; defaultValue = "\"\""; deprecate("deprecated arg")
Expand All @@ -514,8 +515,8 @@ class SchemaPrinterTest {
type Query {
data(
oldOptional: String = "" @deprecated(reason: "deprecated arg")
new: String!
oldOptional: String = "" @deprecated(reason: "deprecated arg")
): String!
}
Expand Down Expand Up @@ -543,6 +544,9 @@ class SchemaPrinterTest {
description = "This is the name"
}
}
inputType<TestObject> {
name = "TestObjectInput"
}
enum<TestEnum> {
value(TestEnum.TYPE1) {
description = "Enum value description"
Expand Down Expand Up @@ -594,7 +598,7 @@ class SchemaPrinterTest {
"Add a test object"
"With some multi-line description"
"(& special characters like " and \n)"
addObject(toAdd: TestObject!): TestObject!
addObject(toAdd: TestObjectInput!): TestObject!
}
"Query object"
Expand Down Expand Up @@ -623,7 +627,7 @@ class SchemaPrinterTest {
TYPE2
}
input TestObject {
input TestObjectInput {
name: String!
}
Expand All @@ -638,6 +642,9 @@ class SchemaPrinterTest {
description = "This is the name"
}
}
inputType<TestObject> {
name = "TestObjectInput"
}
enum<TestEnum> {
value(TestEnum.TYPE1) {
description = "Enum value description"
Expand All @@ -663,7 +670,7 @@ class SchemaPrinterTest {

SchemaPrinter(SchemaPrinterConfig(includeDescriptions = false)).print(schema) shouldBeEqualTo """
type Mutation {
addObject(toAdd: TestObject!): TestObject!
addObject(toAdd: TestObjectInput!): TestObject!
}
type Query {
Expand All @@ -683,7 +690,7 @@ class SchemaPrinterTest {
TYPE2
}
input TestObject {
input TestObjectInput {
name: String!
}
Expand Down

0 comments on commit 99117f0

Please sign in to comment.