Skip to content

Default value not initialized for non-null Int query param in Kotlin request builders #880

@kbrooks

Description

@kbrooks

Issue Description

Currently the code generation for Kotlin requests does not properly initialize a default value for an Int value in the builder code.

Describe your bug in detail.

Steps to Reproduce

friends.graphqls

type Query {
    friends(num: Int!): [Friend]
}

type Friend {
    name: String
}

failing test

package com.kobylynskyi.graphql.codegen.kotlin;

import com.kobylynskyi.graphql.codegen.TestUtils;
import com.kobylynskyi.graphql.codegen.java.JavaGraphQLCodegen;
import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage;
import com.kobylynskyi.graphql.codegen.model.MappingConfig;
import com.kobylynskyi.graphql.codegen.utils.Utils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.Objects;

import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent;
import static com.kobylynskyi.graphql.codegen.TestUtils.getFileByName;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;

class GraphQLCodegenRequestTest {

    private final File outputBuildDir = new File("build/generated");
    private final File outputJavaClassesDir = new File("build/generated/com/github/graphql");
    private final MappingConfig mappingConfig = new MappingConfig();

    @BeforeEach
    void init() {
        mappingConfig.setGeneratedLanguage(GeneratedLanguage.KOTLIN);
        mappingConfig.setResponseProjectionSuffix("ResponseProjection");
        mappingConfig.setGenerateBuilder(true);
        mappingConfig.setGenerateClient(true);
    }

    @AfterEach
    void cleanup() {
        Utils.deleteDir(outputBuildDir);
    }

    @Test
    void generate_RequestAndResponseProjections() throws Exception {
        new KotlinGraphQLCodegen(singletonList("src/test/resources/schemas/requiredQuery.graphqls"),
                outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate();

        File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles());
                assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/" +
                        "FriendsQueryRequest.kt.txt"),
                getFileByName(files, "FriendsQueryRequest.kt"));
    }
}

output is

package com.github.graphql

import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation
import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest
import java.util.Objects

@javax.annotation.Generated(
    value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"],
    date = "2020-12-31T23:59:59-0500"
)
open class FriendsQueryRequest(private val alias: String?) : GraphQLOperationRequest {

    companion object {
        const val OPERATION_NAME: String = "friends"
        val OPERATION_TYPE: GraphQLOperation = GraphQLOperation.QUERY

        @JvmStatic fun builder(): Builder = Builder()
    }

    private val input: MutableMap<String, Any?> = LinkedHashMap()
    private val useObjectMapperForInputSerialization: MutableSet<String> = HashSet()

    constructor(): this(null)

    fun setNum(num: Int) {
        this.input["num"] = num
    }

    override fun getOperationType(): GraphQLOperation = OPERATION_TYPE

    override fun getOperationName(): String = OPERATION_NAME

    override fun getAlias(): String? = alias ?: OPERATION_NAME

    override fun getInput(): MutableMap<String, Any?> = input

    override fun getUseObjectMapperForInputSerialization(): MutableSet<String> = useObjectMapperForInputSerialization

    override fun toString(): String = Objects.toString(input)

    class Builder {

        private var `$alias`: String? = null
        private var num: Int = default

        fun alias(alias: String?): Builder {
            this.`$alias` = alias
            return this
        }

        fun setNum(num: Int): Builder {
            this.num = num
            return this
        }

        fun build(): FriendsQueryRequest {
            val obj = FriendsQueryRequest(`$alias`)
            obj.setNum(num)
            return obj
        }

    }
}

So you can see how the default value is not being initialized for var num: Int

List in detail the exact steps to reproduce the unexpected behavior.

Copy test files

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingkotlinPull requests that update Kotlin code

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions