diff --git a/openapi-generator-config-go.yml b/openapi-generator-config-go.yml new file mode 100644 index 0000000..f78db9e --- /dev/null +++ b/openapi-generator-config-go.yml @@ -0,0 +1,7 @@ +templateDir: templates/go +files: + custom/model_test.mustache: + # TODO: this should be 'ModelTests' instead of 'Model' + # 'Model' was used because 'ModelTests' didn't stick to golangs file naming conventions + templateType: Model + destinationFilename: _test.go diff --git a/scripts/generate-sdk/languages/go.sh b/scripts/generate-sdk/languages/go.sh index d79f9b0..0c4cf6a 100644 --- a/scripts/generate-sdk/languages/go.sh +++ b/scripts/generate-sdk/languages/go.sh @@ -153,15 +153,16 @@ generate_go_sdk() { --input-spec ${service_json} \ --output ${SERVICES_FOLDER}/${service} \ --package-name ${service} \ - --template-dir ${ROOT_DIR}/templates/go/ \ --enable-post-process-file \ --git-host ${GIT_HOST} \ --git-user-id ${GIT_USER_ID} \ --git-repo-id ${GIT_REPO_ID} \ --global-property apis,models,modelTests=true,modelDocs=false,apiDocs=false,supportingFiles \ --additional-properties=isGoSubmodule=true,enumClassPrefix=true,generateInterfaces=true,$regional_api \ - --http-user-agent stackit-sdk-go/${service} \ - --reserved-words-mappings type=types + --http-user-agent stackit-sdk-go/${service} \ + --reserved-words-mappings type=types \ + --config openapi-generator-config-go.yml + # Remove unnecessary files rm ${SERVICES_FOLDER}/${service}/.openapi-generator-ignore rm ${SERVICES_FOLDER}/${service}/.openapi-generator/FILES diff --git a/templates/go/custom/model_simple_test.mustache b/templates/go/custom/model_simple_test.mustache new file mode 100644 index 0000000..f6bde36 --- /dev/null +++ b/templates/go/custom/model_simple_test.mustache @@ -0,0 +1,49 @@ +{{! NOTE: This is a custom STACKIT template which is not present in upsteam to support testing of enum models}} + +{{#vars}} +{{! special handling for enums}} +{{#isEnumRef}} +{{#isEnum}} +// isEnum + +func Test{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}_UnmarshalJSON(t *testing.T) { + type args struct { + src []byte + } + tests := []struct { + name string + args args + wantErr bool + }{ + {{#allowableValues}} + {{#enumVars}} + { + name: `success - possible enum value no. {{-index}}`, + args: args{ + src: []byte(`{{{value}}}`), + }, + wantErr: false, + }, + {{/enumVars}} + {{/allowableValues}} + { + name: "fail", + args: args{ + src: []byte("\"FOOBAR\""), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}({{#isNumeric}}-1{{/isNumeric}}{{^isNumeric}}""{{/isNumeric}}) + if err := v.UnmarshalJSON(tt.args.src); (err != nil) != tt.wantErr { + t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +{{/isEnum}} +{{/isEnumRef}} +{{/vars}} \ No newline at end of file diff --git a/templates/go/custom/model_test.mustache b/templates/go/custom/model_test.mustache new file mode 100644 index 0000000..65e6577 --- /dev/null +++ b/templates/go/custom/model_test.mustache @@ -0,0 +1,20 @@ +{{#models}} + +{{>partial_header}} +package {{packageName}} + +import ( + "testing" +{{#imports}} + "{{import}}" +{{/imports}} +) + +{{#model}} +{{^isEnum}} +{{^oneOf}}{{^anyOf}} +{{>custom/model_simple_test}} +{{/anyOf}}{{/oneOf}} +{{/isEnum}} +{{/model}} +{{/models}} diff --git a/templates/go/model_simple.mustache b/templates/go/model_simple.mustache index 7d6cecf..ee0e605 100644 --- a/templates/go/model_simple.mustache +++ b/templates/go/model_simple.mustache @@ -305,13 +305,16 @@ var Allowed{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titl } func (v *{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) UnmarshalJSON(src []byte) error { - var value {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} + // use a type alias to prevent infinite recursion during unmarshal, + // see https://biscuit.ninja/posts/go-avoid-an-infitine-loop-with-custom-json-unmarshallers + type TmpJson {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} + var value TmpJson err := json.Unmarshal(src, &value) if err != nil { return err } // Allow unmarshalling zero value for testing purposes - var zeroValue {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} + var zeroValue TmpJson if value == zeroValue { return nil }