Skip to content

Commit 7145b2c

Browse files
openapi3: reference originating locations in YAML specs - step 2 (#1024)
* add origin to example * remove unneeded test * add origin to xml * document origin extra field in example
1 parent c333b34 commit 7145b2c

File tree

6 files changed

+120
-22
lines changed

6 files changed

+120
-22
lines changed

.github/docs/openapi3.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ func (encoding *Encoding) WithHeaderRef(name string, ref *HeaderRef) *Encoding
468468

469469
type Example struct {
470470
Extensions map[string]any `json:"-" yaml:"-"`
471+
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`
471472

472473
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
473474
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -2240,6 +2241,7 @@ type ValidationOptions struct {
22402241

22412242
type XML struct {
22422243
Extensions map[string]any `json:"-" yaml:"-"`
2244+
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`
22432245

22442246
Name string `json:"name,omitempty" yaml:"name,omitempty"`
22452247
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`

openapi3/example.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#example-object
1111
type Example struct {
1212
Extensions map[string]any `json:"-" yaml:"-"`
13+
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`
1314

1415
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
1516
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -59,6 +60,7 @@ func (example *Example) UnmarshalJSON(data []byte) error {
5960
return unmarshalError(err)
6061
}
6162
_ = json.Unmarshal(data, &x.Extensions)
63+
delete(x.Extensions, originKey)
6264
delete(x.Extensions, "summary")
6365
delete(x.Extensions, "description")
6466
delete(x.Extensions, "value")

openapi3/origin_test.go

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,11 @@ package openapi3
22

33
import (
44
"context"
5-
"fmt"
6-
"os"
75
"testing"
86

97
"github.com/stretchr/testify/require"
108
)
119

12-
func TestOrigin_All(t *testing.T) {
13-
loader := NewLoader()
14-
loader.IsExternalRefsAllowed = true
15-
loader.IncludeOrigin = true
16-
loader.Context = context.Background()
17-
18-
const dir = "testdata/origin/"
19-
items, _ := os.ReadDir(dir)
20-
for _, item := range items {
21-
t.Run(item.Name(), func(t *testing.T) {
22-
doc, err := loader.LoadFromFile(fmt.Sprintf("%s/%s", dir, item.Name()))
23-
require.NoError(t, err)
24-
if doc.Paths == nil {
25-
t.Skip("no paths")
26-
}
27-
require.NotEmpty(t, doc.Paths.Origin)
28-
})
29-
}
30-
}
31-
3210
func TestOrigin_Info(t *testing.T) {
3311
loader := NewLoader()
3412
loader.IsExternalRefsAllowed = true
@@ -301,3 +279,72 @@ func TestOrigin_Security(t *testing.T) {
301279
},
302280
base.Flows.Implicit.Origin.Fields["authorizationUrl"])
303281
}
282+
283+
func TestOrigin_Example(t *testing.T) {
284+
loader := NewLoader()
285+
loader.IsExternalRefsAllowed = true
286+
loader.IncludeOrigin = true
287+
loader.Context = context.Background()
288+
289+
doc, err := loader.LoadFromFile("testdata/origin/example.yaml")
290+
require.NoError(t, err)
291+
292+
base := doc.Paths.Find("/subscribe").Post.RequestBody.Value.Content["application/json"].Examples["bar"].Value
293+
require.NotNil(t, base.Origin)
294+
require.Equal(t,
295+
&Location{
296+
Line: 14,
297+
Column: 15,
298+
},
299+
base.Origin.Key)
300+
301+
require.Equal(t,
302+
Location{
303+
Line: 15,
304+
Column: 17,
305+
},
306+
base.Origin.Fields["summary"])
307+
308+
// Note:
309+
// Example.Value contains an extra field: "origin".
310+
//
311+
// Explanation:
312+
// The example value is defined in the original yaml file as a json object: {"bar": "baz"}
313+
// This json object is also valid in YAML, so yaml.3 decodes it as a map and adds an "origin" field.
314+
require.Contains(t,
315+
base.Value,
316+
originKey)
317+
}
318+
319+
func TestOrigin_XML(t *testing.T) {
320+
loader := NewLoader()
321+
loader.IsExternalRefsAllowed = true
322+
loader.IncludeOrigin = true
323+
loader.Context = context.Background()
324+
325+
doc, err := loader.LoadFromFile("testdata/origin/xml.yaml")
326+
require.NoError(t, err)
327+
328+
base := doc.Paths.Find("/subscribe").Post.RequestBody.Value.Content["application/json"].Schema.Value.Properties["name"].Value.XML
329+
require.NotNil(t, base.Origin)
330+
require.Equal(t,
331+
&Location{
332+
Line: 21,
333+
Column: 19,
334+
},
335+
base.Origin.Key)
336+
337+
require.Equal(t,
338+
Location{
339+
Line: 22,
340+
Column: 21,
341+
},
342+
base.Origin.Fields["namespace"])
343+
344+
require.Equal(t,
345+
Location{
346+
Line: 23,
347+
Column: 21,
348+
},
349+
base.Origin.Fields["prefix"])
350+
}

openapi3/testdata/origin/example.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Security Requirement Example
4+
version: 1.0.0
5+
paths:
6+
/subscribe:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
examples:
14+
bar:
15+
summary: A bar example
16+
value: {"bar": "baz"}
17+
responses:
18+
"200":
19+
description: OK

openapi3/testdata/origin/xml.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Security Requirement Example
4+
version: 1.0.0
5+
paths:
6+
/subscribe:
7+
post:
8+
requestBody:
9+
content:
10+
application/json:
11+
schema:
12+
type: object
13+
properties:
14+
id:
15+
type: integer
16+
format: int32
17+
xml:
18+
attribute: true
19+
name:
20+
type: string
21+
xml:
22+
namespace: http://example.com/schema/sample
23+
prefix: sample
24+
responses:
25+
"200":
26+
description: OK

openapi3/xml.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-object
1010
type XML struct {
1111
Extensions map[string]any `json:"-" yaml:"-"`
12+
Origin *Origin `json:"origin,omitempty" yaml:"origin,omitempty"`
1213

1314
Name string `json:"name,omitempty" yaml:"name,omitempty"`
1415
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
@@ -58,6 +59,7 @@ func (xml *XML) UnmarshalJSON(data []byte) error {
5859
return unmarshalError(err)
5960
}
6061
_ = json.Unmarshal(data, &x.Extensions)
62+
delete(x.Extensions, originKey)
6163
delete(x.Extensions, "name")
6264
delete(x.Extensions, "namespace")
6365
delete(x.Extensions, "prefix")

0 commit comments

Comments
 (0)