Skip to content

Commit d308378

Browse files
authored
fix drilling down additionalProperties in the boolean case (#378)
1 parent 5ffbbe3 commit d308378

File tree

4 files changed

+71
-11
lines changed

4 files changed

+71
-11
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969
cd openapi3/testdata
7070
go get -u -v github.com/getkin/kin-openapi
7171
go test -tags with_embed ./...
72+
git --no-pager diff && git checkout -- .
7273
cd -
7374
if: matrix.go != '1.14'
7475
- if: runner.os == 'Linux'

openapi3/issue376_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package openapi3
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -40,3 +41,62 @@ info:
4041

4142
require.Equal(t, "string", doc.Components.Schemas["schema2"].Value.Properties["prop"].Value.Type)
4243
}
44+
45+
func TestMultijsonTagSerialization(t *testing.T) {
46+
spec := []byte(`
47+
openapi: 3.0.0
48+
components:
49+
schemas:
50+
unset:
51+
type: number
52+
#empty-object:
53+
# TODO additionalProperties: {}
54+
object:
55+
additionalProperties: {type: string}
56+
boolean:
57+
additionalProperties: false
58+
paths: {}
59+
info:
60+
title: An API
61+
version: 1.2.3.4
62+
`)
63+
64+
loader := NewLoader()
65+
66+
doc, err := loader.LoadFromData(spec)
67+
require.NoError(t, err)
68+
69+
err = doc.Validate(loader.Context)
70+
require.NoError(t, err)
71+
72+
for propName, propSchema := range doc.Components.Schemas {
73+
ap := propSchema.Value.AdditionalProperties
74+
apa := propSchema.Value.AdditionalPropertiesAllowed
75+
76+
encoded, err := propSchema.MarshalJSON()
77+
require.NoError(t, err)
78+
require.Equal(t, string(encoded), map[string]string{
79+
"unset": `{"type":"number"}`,
80+
// TODO: "empty-object":`{"additionalProperties":{}}`,
81+
"object": `{"additionalProperties":{"type":"string"}}`,
82+
"boolean": `{"additionalProperties":false}`,
83+
}[propName])
84+
85+
if propName == "unset" {
86+
require.True(t, ap == nil && apa == nil)
87+
continue
88+
}
89+
90+
apStr := ""
91+
if ap != nil {
92+
apStr = fmt.Sprintf("{Ref:%s Value.Type:%v}", (*ap).Ref, (*ap).Value.Type)
93+
}
94+
apaStr := ""
95+
if apa != nil {
96+
apaStr = fmt.Sprintf("%v", *apa)
97+
}
98+
99+
require.Truef(t, (ap != nil && apa == nil) || (ap == nil && apa != nil),
100+
"%s: isnil(%s) xor isnil(%s)", propName, apaStr, apStr)
101+
}
102+
}

openapi3/loader.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,10 @@ func (loader *Loader) resolveComponent(
351351
func drillIntoField(cursor interface{}, fieldName string) (interface{}, error) {
352352
// Special case due to multijson
353353
if s, ok := cursor.(*SchemaRef); ok && fieldName == "additionalProperties" {
354-
if ap := s.Value.AdditionalProperties; ap != nil {
355-
return ap, nil
354+
if ap := s.Value.AdditionalPropertiesAllowed; ap != nil {
355+
return *ap, nil
356356
}
357-
return s.Value.AdditionalPropertiesAllowed, nil
357+
return s.Value.AdditionalProperties, nil
358358
}
359359

360360
switch val := reflect.Indirect(reflect.ValueOf(cursor)); val.Kind() {

openapi3/schema.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ type Schema struct {
109109
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
110110
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
111111

112-
// Object-related, here for struct compactness
113-
AdditionalPropertiesAllowed *bool `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"`
114112
// Array-related, here for struct compactness
115113
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
116114
// Number-related, here for struct compactness
@@ -141,12 +139,13 @@ type Schema struct {
141139
Items *SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
142140

143141
// Object
144-
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
145-
Properties Schemas `json:"properties,omitempty" yaml:"properties,omitempty"`
146-
MinProps uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
147-
MaxProps *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
148-
AdditionalProperties *SchemaRef `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"`
149-
Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
142+
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
143+
Properties Schemas `json:"properties,omitempty" yaml:"properties,omitempty"`
144+
MinProps uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
145+
MaxProps *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
146+
AdditionalPropertiesAllowed *bool `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"` // In this order...
147+
AdditionalProperties *SchemaRef `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"` // ...for multijson
148+
Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
150149
}
151150

152151
var _ jsonpointer.JSONPointable = (*Schema)(nil)

0 commit comments

Comments
 (0)