Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class CodeGen private constructor(
)
}

private val dependencyTypeMappings = mutableMapOf<String, String>()
private val document = buildDocument()
private val schemaIndex = SchemaIndex(document)
private val requiredTypes: Set<String> by lazy {
Expand All @@ -164,6 +165,13 @@ class CodeGen private constructor(
typeName in requiredTypes

fun generate(): CodeGenResult {
// Apply dependency mappings at generation time so callers can change their mappings after
// constructing CodeGen. User-provided mappings take precedence over dependency mappings.
// Without dependency mappings the caller's map is left untouched, as in 8.7.0.
if (dependencyTypeMappings.isNotEmpty()) {
config.typeMapping = dependencyTypeMappings + config.typeMapping
}

val generated =
when (config.language) {
Language.JAVA -> generateJava()
Expand Down Expand Up @@ -267,10 +275,10 @@ class CodeGen private constructor(
val props = Properties()
props.load(typeMappingInput)

// Add the new type mappings from dependencies to existing type mappings.
// The user provided config overrides mappings from the dependencies.
@Suppress("UNCHECKED_CAST")
config.typeMapping = (props as Map<String, String>).plus(config.typeMapping)
// Earlier dependencies take precedence over later ones, matching the
// previous merge order. User mappings are applied in generate().
val mappings = props.stringPropertyNames().associateWith(props::getProperty)
dependencyTypeMappings.putAll(mappings + dependencyTypeMappings)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6883,6 +6883,143 @@ It takes a title and such.
).isEqualTo("java.lang.String")
}

@Test
fun `Codegen should apply dependency type mappings after caller changes config`() {
val typeMappingDependency =
createSchemaJar(
"""
type Query { invoice: Invoice }
type Invoice { money: Money }
type Money { amount: Int }
""".trimIndent(),
"Money=com.acme.Money",
)
val config =
CodeGenConfig(
schemaJarFilesFromDependencies = listOf(typeMappingDependency),
packageName = BASE_PACKAGE_NAME,
)
val codeGen = CodeGen(config)

assertThat(config.typeMapping).isEmpty()

config.typeMapping = mapOf("Other" to "x.Other")
Comment thread
iuliiasobolevska marked this conversation as resolved.

val result = codeGen.generate()

assertThat(config.typeMapping)
.containsEntry("Money", "com.acme.Money")
.containsEntry("Other", "x.Other")
assertThat(result.javaDataTypes).noneMatch { it.typeSpec().name() == "Money" }
assertThat(
result.javaDataTypes
.single { it.typeSpec().name() == "Invoice" }
.typeSpec()
.fieldSpecs()
.single()
.type()
.toString(),
).isEqualTo("com.acme.Money")

val repeatedResult = codeGen.generate()

assertThat(config.typeMapping)
.containsEntry("Money", "com.acme.Money")
.containsEntry("Other", "x.Other")
assertThat(repeatedResult.javaDataTypes.map { it.typeSpec().toString() })
.isEqualTo(result.javaDataTypes.map { it.typeSpec().toString() })

config.typeMapping = mapOf("Money" to "x.Money", "Other" to "x.Other")

assertThat(invoiceMoneyType(codeGen.generate())).isEqualTo("x.Money")
assertThat(config.typeMapping).containsEntry("Money", "x.Money")
}

@Test
fun `Codegen should honor caller map mutations between generate calls without dependency mappings`() {
val schema =
"""
type Query { invoice: Invoice }
type Invoice { money: Money }
type Money { amount: Int }
""".trimIndent()
val callerMap = mutableMapOf<String, String>()
val config = CodeGenConfig(schemas = setOf(schema), packageName = BASE_PACKAGE_NAME, typeMapping = callerMap)
val codeGen = CodeGen(config)

assertThat(invoiceMoneyType(codeGen.generate())).isEqualTo("$BASE_PACKAGE_NAME.types.Money")

callerMap["Money"] = "com.acme.Money"

assertThat(invoiceMoneyType(codeGen.generate())).isEqualTo("com.acme.Money")
assertThat(config.typeMapping).isSameAs(callerMap)
}

@Test
fun `Codegen should honor caller map mutations when dependency jar has no type mappings`() {
val schemaJar =
createSchemaJar(
"""
type Query { invoice: Invoice }
type Invoice { money: Money }
type Money { amount: Int }
""".trimIndent(),
)
val callerMap = mutableMapOf<String, String>()
val config =
CodeGenConfig(
schemaJarFilesFromDependencies = listOf(schemaJar),
packageName = BASE_PACKAGE_NAME,
typeMapping = callerMap,
)
val codeGen = CodeGen(config)

assertThat(invoiceMoneyType(codeGen.generate())).isEqualTo("$BASE_PACKAGE_NAME.types.Money")

callerMap["Money"] = "com.acme.Money"

assertThat(invoiceMoneyType(codeGen.generate())).isEqualTo("com.acme.Money")
assertThat(config.typeMapping).isSameAs(callerMap)
}

private fun invoiceMoneyType(result: CodeGenResult): String =
result.javaDataTypes
.single { it.typeSpec().name() == "Invoice" }
.typeSpec()
.fieldSpecs()
.single()
.type()
.toString()

@Test
fun `Codegen should preserve earlier dependency type mapping precedence`() {
val firstDependency =
createSchemaJar(
"""
type Query { item: Item }
type Item { amount: Int }
""".trimIndent(),
"Item=com.acme.FirstItem",
)
val secondDependency =
createSchemaJar(
"""
extend type Query { other: Other }
type Other { amount: Int }
""".trimIndent(),
"Item=com.acme.SecondItem",
)
val config =
CodeGenConfig(
schemaJarFilesFromDependencies = listOf(firstDependency, secondDependency),
packageName = BASE_PACKAGE_NAME,
)

CodeGen(config).generate()

assertThat(config.typeMapping).containsEntry("Item", "com.acme.FirstItem")
}

@Test
fun `Codegen should generate schema with unsigned int`() {
val schema =
Expand Down
Loading