Skip to content

Commit 8da91f9

Browse files
committed
fix: oneOfs with enums and strings can not be parsed
1 parent ec3ed8b commit 8da91f9

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{{! NOTE: This is a custom STACKIT template which is not present in upsteam to support testing of oneOf models}}
2+
3+
4+
{{! tests only the adjusted cases in the Generator of UnmarshalJSON}}
5+
{{#useOneOfDiscriminatorLookup}}
6+
{{^discriminator}}
7+
// isOneOf
8+
9+
{{#composedSchemas.oneOf}}
10+
{{#-first}}
11+
func Test{{{classname}}}_UnmarshalJSON(t *testing.T) {
12+
type args struct {
13+
src []byte
14+
}
15+
tests := []struct {
16+
name string
17+
args args
18+
wantErr bool
19+
}{
20+
{{/-first}}
21+
{{#allowableValues.values}}
22+
{
23+
name: "success - {{dataType}} {{.}}",
24+
args: args{
25+
src: []byte(`"{{.}}"`),
26+
},
27+
wantErr: false,
28+
},
29+
{{/allowableValues.values}}
30+
{{^allowableValues.values}}{{^isModel}}
31+
{
32+
name: "success - {{dataType}} {{example}}",
33+
args: args{
34+
src: []byte(`"{{example}}"`),
35+
},
36+
wantErr: false,
37+
},
38+
{{/isModel}}{{/allowableValues.values}}
39+
{{#-last}}
40+
}
41+
for _, tt := range tests {
42+
t.Run(tt.name, func(t *testing.T) {
43+
v := &{{{classname}}}{}
44+
if err := v.UnmarshalJSON(tt.args.src); (err != nil) != tt.wantErr {
45+
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
46+
}
47+
})
48+
}
49+
}
50+
{{/-last}}
51+
{{/composedSchemas.oneOf}}
52+
53+
{{/discriminator}}
54+
{{/useOneOfDiscriminatorLookup}}

templates/go/custom/model_test.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import (
1212

1313
{{#model}}
1414
{{^isEnum}}
15+
{{#oneOf}}
16+
{{#-first}}{{>custom/model_oneof_test}}{{/-first}}
17+
{{/oneOf}}
1518
{{^oneOf}}{{^anyOf}}
1619
{{>custom/model_simple_test}}
1720
{{/anyOf}}{{/oneOf}}

templates/go/model_oneof.mustache

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,36 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
5454
{{/discriminator}}
5555
{{^discriminator}}
5656
match := 0
57-
{{#oneOf}}
57+
{{! Workaround in case oneOf contains enums and strings. The enum value would match with both. }}
58+
{{! The workaround adds a regex check for the string (in case the api spec provides a regex) }}
59+
{{#composedSchemas.oneOf}}
60+
{{#dataType}}
5861
// try to unmarshal data into {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}
5962
err = json.Unmarshal(data, &dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}})
6063
if err == nil {
6164
json{{{.}}}, _ := json.Marshal(dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}})
65+
{{#pattern}}
66+
regex := `{{.}}`
67+
regex = regexp.MustCompile("^\\/|\\/$").ReplaceAllString(regex, "$1") // Remove beginning slash and ending slash
68+
regex = regexp.MustCompile("\\\\(.)").ReplaceAllString(regex, "$1") // Remove duplicate escaping char for dots
69+
rawString := strings.Trim(*dst.String, "\"")
70+
{{/pattern}}
6271
if string(json{{{.}}}) == "{}" { // empty struct
6372
dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil
64-
} else {
73+
{{#pattern}}
74+
} else if matched, _ := regexp.MatchString(regex, rawString); matched {
75+
{{/pattern}}
76+
{{^pattern}}
77+
} else {
78+
{{/pattern}}
6579
match++
6680
}
6781
} else {
6882
dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil
6983
}
7084

71-
{{/oneOf}}
85+
{{/dataType}}
86+
{{/composedSchemas.oneOf}}
7287
if match > 1 { // more than 1 match
7388
// reset to nil
7489
{{#oneOf}}

0 commit comments

Comments
 (0)