diff --git a/datamodel/low/extraction_functions_test.go b/datamodel/low/extraction_functions_test.go index 16d6310..6be9e37 100644 --- a/datamodel/low/extraction_functions_test.go +++ b/datamodel/low/extraction_functions_test.go @@ -4,219 +4,219 @@ package low import ( - "context" - "crypto/sha256" - "fmt" - "net/url" - "os" - "path/filepath" - "runtime" - "strings" - "testing" + "context" + "crypto/sha256" + "fmt" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" + "testing" - "golang.org/x/sync/syncmap" - "gopkg.in/yaml.v3" + "golang.org/x/sync/syncmap" + "gopkg.in/yaml.v3" - "github.com/pb33f/libopenapi/index" - "github.com/pb33f/libopenapi/orderedmap" - "github.com/pb33f/libopenapi/utils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/pb33f/libopenapi/index" + "github.com/pb33f/libopenapi/orderedmap" + "github.com/pb33f/libopenapi/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFindItemInOrderedMap(t *testing.T) { - v := orderedmap.New[KeyReference[string], ValueReference[string]]() - v.Set(KeyReference[string]{ - Value: "pizza", - }, ValueReference[string]{ - Value: "pie", - }) - assert.Equal(t, "pie", FindItemInOrderedMap("pizza", v).Value) + v := orderedmap.New[KeyReference[string], ValueReference[string]]() + v.Set(KeyReference[string]{ + Value: "pizza", + }, ValueReference[string]{ + Value: "pie", + }) + assert.Equal(t, "pie", FindItemInOrderedMap("pizza", v).Value) } func TestFindItemInOrderedMap_WrongCase(t *testing.T) { - v := orderedmap.New[KeyReference[string], ValueReference[string]]() - v.Set(KeyReference[string]{ - Value: "pizza", - }, ValueReference[string]{ - Value: "pie", - }) - assert.Equal(t, "pie", FindItemInOrderedMap("PIZZA", v).Value) + v := orderedmap.New[KeyReference[string], ValueReference[string]]() + v.Set(KeyReference[string]{ + Value: "pizza", + }, ValueReference[string]{ + Value: "pie", + }) + assert.Equal(t, "pie", FindItemInOrderedMap("PIZZA", v).Value) } func TestFindItemInOrderedMap_Error(t *testing.T) { - v := orderedmap.New[KeyReference[string], ValueReference[string]]() - v.Set(KeyReference[string]{ - Value: "pizza", - }, ValueReference[string]{ - Value: "pie", - }) - assert.Nil(t, FindItemInOrderedMap("nuggets", v)) + v := orderedmap.New[KeyReference[string], ValueReference[string]]() + v.Set(KeyReference[string]{ + Value: "pizza", + }, ValueReference[string]{ + Value: "pie", + }) + assert.Nil(t, FindItemInOrderedMap("nuggets", v)) } func TestLocateRefNode(t *testing.T) { - yml := `components: + yml := `components: schemas: cake: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/components/schemas/cake'` + yml = `$ref: '#/components/schemas/cake'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - located, _, _ := LocateRefNode(cNode.Content[0], idx) - assert.NotNil(t, located) + located, _, _ := LocateRefNode(cNode.Content[0], idx) + assert.NotNil(t, located) } func TestLocateRefNode_BadNode(t *testing.T) { - yml := `components: + yml := `components: schemas: cake: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `yes: mate` // useless. + yml = `yes: mate` // useless. - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - located, _, err := LocateRefNode(cNode.Content[0], idx) + located, _, err := LocateRefNode(cNode.Content[0], idx) - // should both be empty. - assert.Nil(t, located) - assert.Nil(t, err) + // should both be empty. + assert.Nil(t, located) + assert.Nil(t, err) } func TestLocateRefNode_Path(t *testing.T) { - yml := `paths: + yml := `paths: /burger/time: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/paths/~1burger~1time'` + yml = `$ref: '#/paths/~1burger~1time'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - located, _, _ := LocateRefNode(cNode.Content[0], idx) - assert.NotNil(t, located) + located, _, _ := LocateRefNode(cNode.Content[0], idx) + assert.NotNil(t, located) } func TestLocateRefNode_Path_NotFound(t *testing.T) { - yml := `paths: + yml := `paths: /burger/time: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/paths/~1burger~1time-somethingsomethingdarkside-somethingsomethingcomplete'` + yml = `$ref: '#/paths/~1burger~1time-somethingsomethingdarkside-somethingsomethingcomplete'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - located, _, err := LocateRefNode(cNode.Content[0], idx) - assert.Nil(t, located) - assert.Error(t, err) + located, _, err := LocateRefNode(cNode.Content[0], idx) + assert.Nil(t, located) + assert.Error(t, err) } type pizza struct { - Description NodeReference[string] + Description NodeReference[string] } func (p *pizza) Build(_ context.Context, _, _ *yaml.Node, _ *index.SpecIndex) error { - return nil + return nil } func TestExtractObject(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `tags: + yml = `tags: description: hello pizza` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) - assert.NoError(t, err) - assert.NotNil(t, tag) - assert.Equal(t, "hello pizza", tag.Value.Description.Value) + tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) + assert.NoError(t, err) + assert.NotNil(t, tag) + assert.Equal(t, "hello pizza", tag.Value.Description.Value) } func TestExtractObject_Ref(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hello pizza` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `tags: + yml = `tags: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) - assert.NoError(t, err) - assert.NotNil(t, tag) - assert.Equal(t, "hello pizza", tag.Value.Description.Value) + tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) + assert.NoError(t, err) + assert.NotNil(t, tag) + assert.Equal(t, "hello pizza", tag.Value.Description.Value) } func TestExtractObject_DoubleRef(t *testing.T) { - yml := `components: + yml := `components: schemas: cake: description: cake time! pizza: $ref: '#/components/schemas/cake'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `tags: + yml = `tags: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) - assert.NoError(t, err) - assert.NotNil(t, tag) - assert.Equal(t, "cake time!", tag.Value.Description.Value) + tag, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) + assert.NoError(t, err) + assert.NotNil(t, tag) + assert.Equal(t, "cake time!", tag.Value.Description.Value) } func TestExtractObject_DoubleRef_Circular(t *testing.T) { - yml := `components: + yml := `components: schemas: loopy: $ref: '#/components/schemas/cake' @@ -225,28 +225,28 @@ func TestExtractObject_DoubleRef_Circular(t *testing.T) { pizza: $ref: '#/components/schemas/cake'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - // circular references are detected by the resolver, so lets run it! - resolv := index.NewResolver(idx) - assert.Len(t, resolv.CheckForCircularReferences(), 1) + // circular references are detected by the resolver, so lets run it! + resolv := index.NewResolver(idx) + assert.Len(t, resolv.CheckForCircularReferences(), 1) - yml = `tags: + yml = `tags: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) - assert.Error(t, err) - assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath()) + _, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) + assert.Error(t, err) + assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath()) } func TestExtractObject_DoubleRef_Circular_Fail(t *testing.T) { - yml := `components: + yml := `components: schemas: loopy: $ref: '#/components/schemas/cake' @@ -255,27 +255,27 @@ func TestExtractObject_DoubleRef_Circular_Fail(t *testing.T) { pizza: $ref: '#/components/schemas/cake'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - // circular references are detected by the resolver, so lets run it! - resolv := index.NewResolver(idx) - assert.Len(t, resolv.CheckForCircularReferences(), 1) + // circular references are detected by the resolver, so lets run it! + resolv := index.NewResolver(idx) + assert.Len(t, resolv.CheckForCircularReferences(), 1) - yml = `tags: + yml = `tags: $ref: #BORK` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) - assert.Error(t, err) + _, err := ExtractObject[*pizza](context.Background(), "tags", &cNode, idx) + assert.Error(t, err) } func TestExtractObject_DoubleRef_Circular_Direct(t *testing.T) { - yml := `components: + yml := `components: schemas: loopy: $ref: '#/components/schemas/cake' @@ -284,27 +284,27 @@ func TestExtractObject_DoubleRef_Circular_Direct(t *testing.T) { pizza: $ref: '#/components/schemas/cake'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - // circular references are detected by the resolver, so lets run it! - resolv := index.NewResolver(idx) - assert.Len(t, resolv.CheckForCircularReferences(), 1) + // circular references are detected by the resolver, so lets run it! + resolv := index.NewResolver(idx) + assert.Len(t, resolv.CheckForCircularReferences(), 1) - yml = `$ref: '#/components/schemas/pizza'` + yml = `$ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*pizza](context.Background(), "tags", cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath()) + _, err := ExtractObject[*pizza](context.Background(), "tags", cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, "cake -> loopy -> cake", idx.GetCircularReferences()[0].GenerateJourneyPath()) } func TestExtractObject_DoubleRef_Circular_Direct_Fail(t *testing.T) { - yml := `components: + yml := `components: schemas: loopy: $ref: '#/components/schemas/cake' @@ -313,117 +313,117 @@ func TestExtractObject_DoubleRef_Circular_Direct_Fail(t *testing.T) { pizza: $ref: '#/components/schemas/cake'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - // circular references are detected by the resolver, so lets run it! - resolv := index.NewResolver(idx) - assert.Len(t, resolv.CheckForCircularReferences(), 1) + // circular references are detected by the resolver, so lets run it! + resolv := index.NewResolver(idx) + assert.Len(t, resolv.CheckForCircularReferences(), 1) - yml = `$ref: '#/components/schemas/why-did-westworld-have-to-end-so-poorly-ffs'` + yml = `$ref: '#/components/schemas/why-did-westworld-have-to-end-so-poorly-ffs'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*pizza](context.Background(), "tags", cNode.Content[0], idx) - assert.Error(t, err) + _, err := ExtractObject[*pizza](context.Background(), "tags", cNode.Content[0], idx) + assert.Error(t, err) } type test_borked struct { - DontWork int + DontWork int } func (t test_borked) Build(_ context.Context, _, root *yaml.Node, idx *index.SpecIndex) error { - return fmt.Errorf("I am always going to fail, every thing") + return fmt.Errorf("I am always going to fail, every thing") } type test_noGood struct { - DontWork int + DontWork int } func (t *test_noGood) Build(_ context.Context, _, root *yaml.Node, idx *index.SpecIndex) error { - return fmt.Errorf("I am always going to fail a core build") + return fmt.Errorf("I am always going to fail a core build") } type test_almostGood struct { - AlmostWork NodeReference[int] + AlmostWork NodeReference[int] } func (t *test_almostGood) Build(_ context.Context, _, root *yaml.Node, idx *index.SpecIndex) error { - return fmt.Errorf("I am always going to fail a build out") + return fmt.Errorf("I am always going to fail a build out") } type test_Good struct { - AlmostWork NodeReference[int] + AlmostWork NodeReference[int] } func (t *test_Good) Build(_ context.Context, _, root *yaml.Node, idx *index.SpecIndex) error { - return nil + return nil } func TestExtractObject_BadLowLevelModel(t *testing.T) { - yml := `components: + yml := `components: schemas: hey:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `thing: + yml = `thing: dontWork: 123` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*test_noGood](context.Background(), "thing", &cNode, idx) - assert.Error(t, err) + _, err := ExtractObject[*test_noGood](context.Background(), "thing", &cNode, idx) + assert.Error(t, err) } func TestExtractObject_BadBuild(t *testing.T) { - yml := `components: + yml := `components: schemas: hey:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `thing: + yml = `thing: dontWork: 123` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err := ExtractObject[*test_almostGood](context.Background(), "thing", &cNode, idx) - assert.Error(t, err) + _, err := ExtractObject[*test_almostGood](context.Background(), "thing", &cNode, idx) + assert.Error(t, err) } func TestExtractObject_BadLabel(t *testing.T) { - yml := `components: + yml := `components: schemas: hey:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `thing: + yml = `thing: dontWork: 123` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - res, err := ExtractObject[*test_almostGood](context.Background(), "ding", &cNode, idx) - assert.Nil(t, res.Value) - assert.NoError(t, err) + res, err := ExtractObject[*test_almostGood](context.Background(), "ding", &cNode, idx) + assert.Nil(t, res.Value) + assert.NoError(t, err) } func TestExtractObject_PathIsCircular(t *testing.T) { - // first we need an index. - yml := `paths: + // first we need an index. + yml := `paths: '/something/here': post: $ref: '#/paths/~1something~1there/post' @@ -431,30 +431,30 @@ func TestExtractObject_PathIsCircular(t *testing.T) { post: $ref: '#/paths/~1something~1here/post'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `thing: + yml = `thing: $ref: '#/paths/~1something~1here/post'` - var rootNode yaml.Node - mErr = yaml.Unmarshal([]byte(yml), &rootNode) - assert.NoError(t, mErr) + var rootNode yaml.Node + mErr = yaml.Unmarshal([]byte(yml), &rootNode) + assert.NoError(t, mErr) - res, err := ExtractObject[*test_Good](context.Background(), "thing", &rootNode, idx) - assert.NotNil(t, res.Value) - assert.Error(t, err) // circular error would have been thrown. + res, err := ExtractObject[*test_Good](context.Background(), "thing", &rootNode, idx) + assert.NotNil(t, res.Value) + assert.Error(t, err) // circular error would have been thrown. } func TestExtractObject_PathIsCircular_IgnoreErrors(t *testing.T) { - // first we need an index. - yml := `paths: + // first we need an index. + yml := `paths: '/something/here': post: $ref: '#/paths/~1something~1there/post' @@ -462,348 +462,348 @@ func TestExtractObject_PathIsCircular_IgnoreErrors(t *testing.T) { post: $ref: '#/paths/~1something~1here/post'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - // disable circular ref checking. - idx.SetAllowCircularReferenceResolving(true) + // disable circular ref checking. + idx.SetAllowCircularReferenceResolving(true) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `thing: + yml = `thing: $ref: '#/paths/~1something~1here/post'` - var rootNode yaml.Node - mErr = yaml.Unmarshal([]byte(yml), &rootNode) - assert.NoError(t, mErr) + var rootNode yaml.Node + mErr = yaml.Unmarshal([]byte(yml), &rootNode) + assert.NoError(t, mErr) - res, err := ExtractObject[*test_Good](context.Background(), "thing", &rootNode, idx) - assert.NotNil(t, res.Value) - assert.NoError(t, err) // circular error would have been thrown, but we're ignoring them. + res, err := ExtractObject[*test_Good](context.Background(), "thing", &rootNode, idx) + assert.NotNil(t, res.Value) + assert.NoError(t, err) // circular error would have been thrown, but we're ignoring them. } func TestExtractObjectRaw(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `description: hello pizza` + yml = `description: hello pizza` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) - assert.NoError(t, err) - assert.NotNil(t, tag) - assert.Equal(t, "hello pizza", tag.Description.Value) + tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) + assert.NoError(t, err) + assert.NotNil(t, tag) + assert.Equal(t, "hello pizza", tag.Description.Value) } func TestExtractObjectRaw_With_Ref(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/components/schemas/pizza'` + yml = `$ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err, isRef, rv := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) - assert.NoError(t, err) - assert.NotNil(t, tag) - assert.Equal(t, "hello", tag.Description.Value) - assert.True(t, isRef) - assert.Equal(t, "#/components/schemas/pizza", rv) + tag, err, isRef, rv := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) + assert.NoError(t, err) + assert.NotNil(t, tag) + assert.Equal(t, "hello", tag.Description.Value) + assert.True(t, isRef) + assert.Equal(t, "#/components/schemas/pizza", rv) } func TestExtractObjectRaw_Ref_Circular(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: $ref: '#/components/schemas/pie' pie: $ref: '#/components/schemas/pizza'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `$ref: '#/components/schemas/pizza'` + yml = `$ref: '#/components/schemas/pizza'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) - assert.Error(t, err) - assert.NotNil(t, tag) + tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) + assert.Error(t, err) + assert.NotNil(t, tag) } func TestExtractObjectRaw_RefBroken(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hey!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/components/schemas/lost-in-space'` + yml = `$ref: '#/components/schemas/lost-in-space'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) - assert.Error(t, err) - assert.Nil(t, tag) + tag, err, _, _ := ExtractObjectRaw[*pizza](context.Background(), nil, cNode.Content[0], idx) + assert.Error(t, err) + assert.Nil(t, tag) } func TestExtractObjectRaw_Ref_NonBuildable(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hey!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `dontWork: 1'` + yml = `dontWork: 1'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err, _, _ := ExtractObjectRaw[*test_noGood](context.Background(), nil, cNode.Content[0], idx) - assert.Error(t, err) + _, err, _, _ := ExtractObjectRaw[*test_noGood](context.Background(), nil, cNode.Content[0], idx) + assert.Error(t, err) } func TestExtractObjectRaw_Ref_AlmostBuildable(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hey!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `almostWork: 1'` + yml = `almostWork: 1'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - _, err, _, _ := ExtractObjectRaw[*test_almostGood](context.Background(), nil, cNode.Content[0], idx) - assert.Error(t, err) + _, err, _, _ := ExtractObjectRaw[*test_almostGood](context.Background(), nil, cNode.Content[0], idx) + assert.Error(t, err) } func TestExtractArray(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: hello` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `things: + yml = `things: - description: one - description: two - description: three` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*pizza](context.Background(), "things", cNode.Content[0], idx) - assert.NoError(t, err) - assert.NotNil(t, things) - assert.Equal(t, "one", things[0].Value.Description.Value) - assert.Equal(t, "two", things[1].Value.Description.Value) - assert.Equal(t, "three", things[2].Value.Description.Value) + things, _, _, err := ExtractArray[*pizza](context.Background(), "things", cNode.Content[0], idx) + assert.NoError(t, err) + assert.NotNil(t, things) + assert.Equal(t, "one", things[0].Value.Description.Value) + assert.Equal(t, "two", things[1].Value.Description.Value) + assert.Equal(t, "three", things[2].Value.Description.Value) } func TestExtractArray_Ref(t *testing.T) { - yml := `components: + yml := `components: schemas: things: - description: one - description: two - description: three` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/components/schemas/things'` + yml = `$ref: '#/components/schemas/things'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*pizza](context.Background(), "things", cNode.Content[0], idx) - assert.NoError(t, err) - assert.NotNil(t, things) - assert.Equal(t, "one", things[0].Value.Description.Value) - assert.Equal(t, "two", things[1].Value.Description.Value) - assert.Equal(t, "three", things[2].Value.Description.Value) + things, _, _, err := ExtractArray[*pizza](context.Background(), "things", cNode.Content[0], idx) + assert.NoError(t, err) + assert.NotNil(t, things) + assert.Equal(t, "one", things[0].Value.Description.Value) + assert.Equal(t, "two", things[1].Value.Description.Value) + assert.Equal(t, "three", things[2].Value.Description.Value) } func TestExtractArray_Ref_Unbuildable(t *testing.T) { - yml := `components: + yml := `components: schemas: things: - description: one - description: two - description: three` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `$ref: '#/components/schemas/things'` + yml = `$ref: '#/components/schemas/things'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*test_noGood](context.Background(), "", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + things, _, _, err := ExtractArray[*test_noGood](context.Background(), "", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractArray_Ref_Circular(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `$ref: '#/components/schemas/things'` + yml = `$ref: '#/components/schemas/things'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 2) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 2) } func TestExtractArray_Ref_Bad(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `$ref: '#/components/schemas/let-us-eat-cake'` + yml = `$ref: '#/components/schemas/let-us-eat-cake'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractArray_Ref_Nested(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `limes: + yml = `limes: $ref: '#/components/schemas/let-us-eat-cake'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractArray_Ref_Nested_Circular(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `limes: + yml = `limes: - $ref: '#/components/schemas/things'` - var cNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &cNode) + var cNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &cNode) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 1) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 1) } func TestExtractArray_Ref_Nested_BadRef(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: allOf: @@ -812,680 +812,680 @@ func TestExtractArray_Ref_Nested_BadRef(t *testing.T) { oneOf: - type: string` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `limes: + yml = `limes: - $ref: '#/components/schemas/thangs'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractArray_Ref_Nested_CircularFlat(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `limes: + yml = `limes: $ref: '#/components/schemas/things'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) - things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 2) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) + things, _, _, err := ExtractArray[*test_Good](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 2) } func TestExtractArray_BadBuild(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `limes: + yml = `limes: - dontWork: 1` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) - things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) + things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractArray_BadRefPropsTupe(t *testing.T) { - yml := `components: + yml := `components: parameters: cakes: limes: cake` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `limes: + yml = `limes: $ref: '#/components/parameters/cakes'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) - things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Len(t, things, 0) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) + things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Len(t, things, 0) } func TestExtractMapFlatNoLookup(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: description: two` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMap_NoLookupWithExtensions(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: x-choo: choo` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, true) - assert.NoError(t, err) - assert.Equal(t, 2, orderedmap.Len(things)) + things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, true) + assert.NoError(t, err) + assert.Equal(t, 2, orderedmap.Len(things)) - for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { - if pair.Key().Value == "x-hey" { - continue - } - assert.Equal(t, "one", pair.Key().Value) - assert.Len(t, pair.Value().ValueNode.Content, 2) - } + for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { + if pair.Key().Value == "x-hey" { + continue + } + assert.Equal(t, "one", pair.Key().Value) + assert.Len(t, pair.Value().ValueNode.Content, 2) + } } func TestExtractMap_NoLookupWithExtensions_UsingMerge(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-yeah: &yeah + yml = `x-yeah: &yeah night: fun x-hey: you one: x-choo: choo <<: *yeah` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, true) - assert.NoError(t, err) - assert.Equal(t, 4, orderedmap.Len(things)) + things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, true) + assert.NoError(t, err) + assert.Equal(t, 4, orderedmap.Len(things)) } func TestExtractMap_NoLookupWithoutExtensions(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: x-choo: choo` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, false) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, err := ExtractMapNoLookupExtensions[*test_Good](context.Background(), cNode.Content[0], idx, false) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) - for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { - assert.Equal(t, "one", pair.Key().Value) - } + for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { + assert.Equal(t, "one", pair.Key().Value) + } } func TestExtractMap_WithExtensions(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: x-choo: choo` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMapExtensions[*test_Good](context.Background(), "one", cNode.Content[0], idx, true) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMapExtensions[*test_Good](context.Background(), "one", cNode.Content[0], idx, true) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMap_WithoutExtensions(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: x-choo: choo` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMapExtensions[*test_Good](context.Background(), "one", cNode.Content[0], idx, false) - assert.NoError(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMapExtensions[*test_Good](context.Background(), "one", cNode.Content[0], idx, false) + assert.NoError(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlatNoLookup_Ref(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: tasty!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlatNoLookup_Ref_Bad(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: tasty!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: $ref: '#/components/schemas/no-where-out-there'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlatNoLookup_Ref_Circular(t *testing.T) { - yml := `components: + yml := `components: schemas: thongs: $ref: '#/components/schemas/things' things: $ref: '#/components/schemas/thongs'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `x-hey: you + yml = `x-hey: you one: $ref: '#/components/schemas/things'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_Good](context.Background(), cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlatNoLookup_Ref_BadBuild(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: dontWork: 1` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you hello: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_noGood](context.Background(), cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_noGood](context.Background(), cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlatNoLookup_Ref_AlmostBuild(t *testing.T) { - yml := `components: + yml := `components: schemas: pizza: description: tasty!` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: $ref: '#/components/schemas/pizza'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, err := ExtractMapNoLookup[*test_almostGood](context.Background(), cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, err := ExtractMapNoLookup[*test_almostGood](context.Background(), cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat(t *testing.T) { - yml := `components:` + yml := `components:` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: description: two` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlat_Ref(t *testing.T) { - yml := `components: + yml := `components: schemas: stank: things: almostWork: 99` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `x-hey: you + yml = `x-hey: you one: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) - for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { - assert.Equal(t, 99, pair.Value().Value.AlmostWork.Value) - } + for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { + assert.Equal(t, 99, pair.Value().Value.AlmostWork.Value) + } } func TestExtractMapFlat_DoubleRef(t *testing.T) { - yml := `components: + yml := `components: schemas: stank: almostWork: 99` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: nice: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.NoError(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.NoError(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) - for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { - assert.Equal(t, 99, pair.Value().Value.AlmostWork.Value) - } + for pair := orderedmap.First(things); pair != nil; pair = pair.Next() { + assert.Equal(t, 99, pair.Value().Value.AlmostWork.Value) + } } func TestExtractMapFlat_DoubleRef_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stank: things: almostWork: 99` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: nice: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat_DoubleRef_Error_NotFound(t *testing.T) { - yml := `components: + yml := `components: schemas: stank: things: almostWork: 99` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: nice: $ref: '#/components/schemas/stanky-panky'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat_DoubleRef_Circles(t *testing.T) { - yml := `components: + yml := `components: schemas: stonk: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/stonk'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `one: + yml = `one: nice: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlat_Ref_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stank: x-smells: bad things: almostWork: 99` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_almostGood](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat_Ref_Circ_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stink: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/stink'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `$ref: '#/components/schemas/stank'` + yml = `$ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlat_Ref_Nested_Circ_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stink: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/stink'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `one: + yml = `one: $ref: '#/components/schemas/stank'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, 1, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, 1, orderedmap.Len(things)) } func TestExtractMapFlat_Ref_Nested_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stink: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/none'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: $ref: '#/components/schemas/somewhere-else'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat_BadKey_Ref_Nested_Error(t *testing.T) { - yml := `components: + yml := `components: schemas: stink: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/none'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `one: + yml = `one: $ref: '#/components/schemas/somewhere-else'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "not-even-there", cNode.Content[0], idx) - assert.NoError(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "not-even-there", cNode.Content[0], idx) + assert.NoError(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractMapFlat_Ref_Bad(t *testing.T) { - yml := `components: + yml := `components: schemas: stink: $ref: '#/components/schemas/stank' stank: $ref: '#/components/schemas/none'` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - resolve := index.NewResolver(idx) - errs := resolve.CheckForCircularReferences() - assert.Len(t, errs, 1) + resolve := index.NewResolver(idx) + errs := resolve.CheckForCircularReferences() + assert.Len(t, errs, 1) - yml = `$ref: '#/components/schemas/somewhere-else'` + yml = `$ref: '#/components/schemas/somewhere-else'` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) - things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) - assert.Error(t, err) - assert.Zero(t, orderedmap.Len(things)) + things, _, _, err := ExtractMap[*test_Good](context.Background(), "one", cNode.Content[0], idx) + assert.Error(t, err) + assert.Zero(t, orderedmap.Len(things)) } func TestExtractExtensions(t *testing.T) { - yml := `x-bing: ding + yml := `x-bing: ding x-bong: 1 x-ling: true x-long: 0.99 @@ -1493,664 +1493,664 @@ x-fish: woo: yeah x-tacos: [1,2,3]` - var idxNode yaml.Node - _ = yaml.Unmarshal([]byte(yml), &idxNode) + var idxNode yaml.Node + _ = yaml.Unmarshal([]byte(yml), &idxNode) - r := ExtractExtensions(idxNode.Content[0]) - assert.Equal(t, 6, orderedmap.Len(r)) - for pair := orderedmap.First(r); pair != nil; pair = pair.Next() { - var v any - _ = pair.Value().Value.Decode(&v) + r := ExtractExtensions(idxNode.Content[0]) + assert.Equal(t, 6, orderedmap.Len(r)) + for pair := orderedmap.First(r); pair != nil; pair = pair.Next() { + var v any + _ = pair.Value().Value.Decode(&v) - switch pair.Key().Value { - case "x-bing": - assert.Equal(t, "ding", v) - case "x-bong": - assert.Equal(t, 1, v) - case "x-ling": - assert.Equal(t, true, v) - case "x-long": - assert.Equal(t, 0.99, v) - case "x-fish": - var m map[string]any - err := pair.Value().Value.Decode(&m) - require.NoError(t, err) - assert.Equal(t, "yeah", m["woo"]) - case "x-tacos": - assert.Len(t, v, 3) - } - } + switch pair.Key().Value { + case "x-bing": + assert.Equal(t, "ding", v) + case "x-bong": + assert.Equal(t, 1, v) + case "x-ling": + assert.Equal(t, true, v) + case "x-long": + assert.Equal(t, 0.99, v) + case "x-fish": + var m map[string]any + err := pair.Value().Value.Decode(&m) + require.NoError(t, err) + assert.Equal(t, "yeah", m["woo"]) + case "x-tacos": + assert.Len(t, v, 3) + } + } } type test_fresh struct { - val string - thang *bool + val string + thang *bool } func (f test_fresh) Hash() [32]byte { - var data []string - if f.val != "" { - data = append(data, f.val) - } - if f.thang != nil { - data = append(data, fmt.Sprintf("%v", *f.thang)) - } - return sha256.Sum256([]byte(strings.Join(data, "|"))) + var data []string + if f.val != "" { + data = append(data, f.val) + } + if f.thang != nil { + data = append(data, fmt.Sprintf("%v", *f.thang)) + } + return sha256.Sum256([]byte(strings.Join(data, "|"))) } func TestAreEqual(t *testing.T) { - var hey *test_fresh + var hey *test_fresh - assert.True(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "hello"})) - assert.True(t, AreEqual(&test_fresh{val: "hello"}, &test_fresh{val: "hello"})) - assert.False(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "goodbye"})) - assert.False(t, AreEqual(&test_fresh{val: "hello"}, &test_fresh{val: "goodbye"})) - assert.False(t, AreEqual(nil, &test_fresh{val: "goodbye"})) - assert.False(t, AreEqual(&test_fresh{val: "hello"}, hey)) - assert.False(t, AreEqual(nil, nil)) + assert.True(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "hello"})) + assert.True(t, AreEqual(&test_fresh{val: "hello"}, &test_fresh{val: "hello"})) + assert.False(t, AreEqual(test_fresh{val: "hello"}, test_fresh{val: "goodbye"})) + assert.False(t, AreEqual(&test_fresh{val: "hello"}, &test_fresh{val: "goodbye"})) + assert.False(t, AreEqual(nil, &test_fresh{val: "goodbye"})) + assert.False(t, AreEqual(&test_fresh{val: "hello"}, hey)) + assert.False(t, AreEqual(nil, nil)) } func TestGenerateHashString(t *testing.T) { - assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", - GenerateHashString(test_fresh{val: "hello"})) + assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", + GenerateHashString(test_fresh{val: "hello"})) - assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", - GenerateHashString("hello")) + assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", + GenerateHashString("hello")) - assert.Equal(t, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - GenerateHashString("")) + assert.Equal(t, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + GenerateHashString("")) - assert.Equal(t, "", - GenerateHashString(nil)) + assert.Equal(t, "", + GenerateHashString(nil)) - assert.Equal(t, "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2", GenerateHashString(utils.CreateStringNode("test"))) + assert.Equal(t, "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2", GenerateHashString(utils.CreateStringNode("test"))) } func TestGenerateHashString_Pointer(t *testing.T) { - val := true - assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b", - GenerateHashString(test_fresh{thang: &val})) + val := true + assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b", + GenerateHashString(test_fresh{thang: &val})) - assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b", - GenerateHashString(&val)) + assert.Equal(t, "b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b", + GenerateHashString(&val)) } func TestSetReference(t *testing.T) { - type testObj struct { - *Reference - } + type testObj struct { + *Reference + } - n := testObj{Reference: &Reference{}} - SetReference(&n, "#/pigeon/street", nil) + n := testObj{Reference: &Reference{}} + SetReference(&n, "#/pigeon/street", nil) - assert.Equal(t, "#/pigeon/street", n.GetReference()) + assert.Equal(t, "#/pigeon/street", n.GetReference()) } func TestSetReference_nil(t *testing.T) { - type testObj struct { - *Reference - } + type testObj struct { + *Reference + } - n := testObj{Reference: &Reference{}} - SetReference(nil, "#/pigeon/street", nil) - assert.NotEqual(t, "#/pigeon/street", n.GetReference()) + n := testObj{Reference: &Reference{}} + SetReference(nil, "#/pigeon/street", nil) + assert.NotEqual(t, "#/pigeon/street", n.GetReference()) } func TestLocateRefNode_CurrentPathKey_HttpLink(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "http://cakes.com/nice#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "http://cakes.com/nice#/components/schemas/thing", + }, + }, + } - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://cakes.com#/components/schemas/thing") + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://cakes.com#/components/schemas/thing") - idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_HttpLink_Local(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: ".#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: ".#/components/schemas/thing", + }, + }, + } - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://cakes.com/nice/rice#/components/schemas/thing") + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://cakes.com/nice/rice#/components/schemas/thing") - idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_HttpLink_RemoteCtx(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "#/components/schemas/thing", + }, + }, + } - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "https://cakes.com#/components/schemas/thing") - idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "https://cakes.com#/components/schemas/thing") + idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_HttpLink_RemoteCtx_WithPath(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "#/components/schemas/thing", + }, + }, + } - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "https://cakes.com/jazzzy/shoes#/components/schemas/thing") - idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "https://cakes.com/jazzzy/shoes#/components/schemas/thing") + idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_Path_Link(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "yazzy.yaml#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "yazzy.yaml#/components/schemas/thing", + }, + }, + } - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "/jazzzy/shoes.yaml") - idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "/jazzzy/shoes.yaml") + idx := index.NewSpecIndexWithConfig(&no, index.CreateClosedAPIIndexConfig()) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_Path_URL(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "yazzy.yaml#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "yazzy.yaml#/components/schemas/thing", + }, + }, + } - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("https://herbs-and-coffee-in-the-fall.com") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&no, cf) - n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("https://herbs-and-coffee-in-the-fall.com") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&no, cf) + n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_CurrentPathKey_DeeperPath_URL(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "slasshy/mazsshy/yazzy.yaml#/components/schemas/thing", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "slasshy/mazsshy/yazzy.yaml#/components/schemas/thing", + }, + }, + } - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("https://herbs-and-coffee-in-the-fall.com/pizza/burgers") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&no, cf) - n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("https://herbs-and-coffee-in-the-fall.com/pizza/burgers") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&no, cf) + n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_NoExplode(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "components/schemas/thing.yaml", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "components/schemas/thing.yaml", + }, + }, + } - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("http://smiledfdfdfdfds.com/bikes") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&no, cf) - n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("http://smiledfdfdfdfds.com/bikes") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&no, cf) + n, i, e, c := LocateRefNodeWithContext(context.Background(), &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_NoExplode_HTTP(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "components/schemas/thing.yaml", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "components/schemas/thing.yaml", + }, + }, + } - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&no, cf) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://minty-fresh-shoes.com/nice/no.yaml") - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&no, cf) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "http://minty-fresh-shoes.com/nice/no.yaml") + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_NoExplode_NoSpecPath(t *testing.T) { - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "components/schemas/thing.yaml", - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "components/schemas/thing.yaml", + }, + }, + } - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&no, cf) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, "no.yaml") - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.NotNil(t, e) - assert.NotNil(t, c) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&no, cf) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, "no.yaml") + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.NotNil(t, e) + assert.NotNil(t, c) } func TestLocateRefNode_DoARealLookup(t *testing.T) { - lookup := "/root.yaml#/components/schemas/Burger" - if runtime.GOOS == "windows" { - lookup = "C:\\root.yaml#/components/schemas/Burger" - } + lookup := "/root.yaml#/components/schemas/Burger" + if runtime.GOOS == "windows" { + lookup = "C:\\root.yaml#/components/schemas/Burger" + } - no := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: lookup, - }, - }, - } + no := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: lookup, + }, + }, + } - b, err := os.ReadFile("../../test_specs/burgershop.openapi.yaml") - if err != nil { - t.Fatal(err) - } - var rootNode yaml.Node - _ = yaml.Unmarshal(b, &rootNode) + b, err := os.ReadFile("../../test_specs/burgershop.openapi.yaml") + if err != nil { + t.Fatal(err) + } + var rootNode yaml.Node + _ = yaml.Unmarshal(b, &rootNode) - cf := index.CreateClosedAPIIndexConfig() - u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") - cf.BaseURL = u - idx := index.NewSpecIndexWithConfig(&rootNode, cf) + cf := index.CreateClosedAPIIndexConfig() + u, _ := url.Parse("http://smilfghfhfhfhfhes.com/bikes") + cf.BaseURL = u + idx := index.NewSpecIndexWithConfig(&rootNode, cf) - // fake cache to a lookup for a file that does not exist will work. - fakeCache := new(syncmap.Map) - fakeCache.Store(lookup, &index.Reference{Node: &no, Index: idx}) - idx.SetCache(fakeCache) + // fake cache to a lookup for a file that does not exist will work. + fakeCache := new(syncmap.Map) + fakeCache.Store(lookup, &index.Reference{Node: &no, Index: idx}) + idx.SetCache(fakeCache) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, lookup) - n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) - assert.NotNil(t, n) - assert.NotNil(t, i) - assert.Nil(t, e) - assert.NotNil(t, c) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, lookup) + n, i, e, c := LocateRefNodeWithContext(ctx, &no, idx) + assert.NotNil(t, n) + assert.NotNil(t, i) + assert.Nil(t, e) + assert.NotNil(t, c) } func TestLocateRefEndNoRef_NoName(t *testing.T) { - r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: ""}}} - n, i, e, c := LocateRefEnd(nil, r, nil, 0) - assert.Nil(t, n) - assert.Nil(t, i) - assert.Error(t, e) - assert.Nil(t, c) + r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: ""}}} + n, i, e, c := LocateRefEnd(nil, r, nil, 0) + assert.Nil(t, n) + assert.Nil(t, i) + assert.Error(t, e) + assert.Nil(t, c) } func TestLocateRefEndNoRef(t *testing.T) { - r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: "cake"}}} - n, i, e, c := LocateRefEnd(context.Background(), r, index.NewSpecIndexWithConfig(r, index.CreateClosedAPIIndexConfig()), 0) - assert.Nil(t, n) - assert.NotNil(t, i) - assert.Error(t, e) - assert.NotNil(t, c) + r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: "cake"}}} + n, i, e, c := LocateRefEnd(context.Background(), r, index.NewSpecIndexWithConfig(r, index.CreateClosedAPIIndexConfig()), 0) + assert.Nil(t, n) + assert.NotNil(t, i) + assert.Error(t, e) + assert.NotNil(t, c) } func TestLocateRefEnd_TooDeep(t *testing.T) { - r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: ""}}} - n, i, e, c := LocateRefEnd(nil, r, nil, 100) - assert.Nil(t, n) - assert.Nil(t, i) - assert.Error(t, e) - assert.Nil(t, c) + r := &yaml.Node{Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: "$ref"}, {Kind: yaml.ScalarNode, Value: ""}}} + n, i, e, c := LocateRefEnd(nil, r, nil, 100) + assert.Nil(t, n) + assert.Nil(t, i) + assert.Error(t, e) + assert.Nil(t, c) } func TestLocateRefEnd_Loop(t *testing.T) { - yml, _ := os.ReadFile("../../test_specs/first.yaml") - var bsn yaml.Node - _ = yaml.Unmarshal(yml, &bsn) + yml, _ := os.ReadFile("../../test_specs/first.yaml") + var bsn yaml.Node + _ = yaml.Unmarshal(yml, &bsn) - cf := index.CreateOpenAPIIndexConfig() - cf.BasePath = "../../test_specs" + cf := index.CreateOpenAPIIndexConfig() + cf.BasePath = "../../test_specs" - localFSConfig := &index.LocalFSConfig{ - BaseDirectory: cf.BasePath, - FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, - DirFS: os.DirFS(cf.BasePath), - } - localFs, _ := index.NewLocalFSWithConfig(localFSConfig) - rolo := index.NewRolodex(cf) - rolo.AddLocalFS(cf.BasePath, localFs) - rolo.SetRootNode(&bsn) - rolo.IndexTheRolodex() + localFSConfig := &index.LocalFSConfig{ + BaseDirectory: cf.BasePath, + FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, + DirFS: os.DirFS(cf.BasePath), + } + localFs, _ := index.NewLocalFSWithConfig(localFSConfig) + rolo := index.NewRolodex(cf) + rolo.AddLocalFS(cf.BasePath, localFs) + rolo.SetRootNode(&bsn) + rolo.IndexTheRolodex() - idx := rolo.GetRootIndex() - loop := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "third.yaml#/properties/property/properties/statistics", - }, - }, - } + idx := rolo.GetRootIndex() + loop := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "third.yaml#/properties/property/properties/statistics", + }, + }, + } - wd, _ := os.Getwd() - cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) - n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) - assert.NotNil(t, n) - assert.NotNil(t, i) - assert.Nil(t, e) - assert.NotNil(t, c) + wd, _ := os.Getwd() + cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) + n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) + assert.NotNil(t, n) + assert.NotNil(t, i) + assert.Nil(t, e) + assert.NotNil(t, c) } func TestLocateRefEnd_Loop_WithResolve(t *testing.T) { - yml, _ := os.ReadFile("../../test_specs/first.yaml") - var bsn yaml.Node - _ = yaml.Unmarshal(yml, &bsn) + yml, _ := os.ReadFile("../../test_specs/first.yaml") + var bsn yaml.Node + _ = yaml.Unmarshal(yml, &bsn) - cf := index.CreateOpenAPIIndexConfig() - cf.BasePath = "../../test_specs" + cf := index.CreateOpenAPIIndexConfig() + cf.BasePath = "../../test_specs" - localFSConfig := &index.LocalFSConfig{ - BaseDirectory: cf.BasePath, - FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, - DirFS: os.DirFS(cf.BasePath), - } - localFs, _ := index.NewLocalFSWithConfig(localFSConfig) - rolo := index.NewRolodex(cf) - rolo.AddLocalFS(cf.BasePath, localFs) - rolo.SetRootNode(&bsn) - rolo.IndexTheRolodex() - rolo.Resolve() - idx := rolo.GetRootIndex() - loop := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "third.yaml#/properties/property/properties/statistics", - }, - }, - } + localFSConfig := &index.LocalFSConfig{ + BaseDirectory: cf.BasePath, + FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, + DirFS: os.DirFS(cf.BasePath), + } + localFs, _ := index.NewLocalFSWithConfig(localFSConfig) + rolo := index.NewRolodex(cf) + rolo.AddLocalFS(cf.BasePath, localFs) + rolo.SetRootNode(&bsn) + rolo.IndexTheRolodex() + rolo.Resolve() + idx := rolo.GetRootIndex() + loop := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "third.yaml#/properties/property/properties/statistics", + }, + }, + } - wd, _ := os.Getwd() - cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) - n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) - assert.NotNil(t, n) - assert.NotNil(t, i) - assert.Nil(t, e) - assert.NotNil(t, c) + wd, _ := os.Getwd() + cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) + n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) + assert.NotNil(t, n) + assert.NotNil(t, i) + assert.Nil(t, e) + assert.NotNil(t, c) } func TestLocateRefEnd_Empty(t *testing.T) { - yml, _ := os.ReadFile("../../test_specs/first.yaml") - var bsn yaml.Node - _ = yaml.Unmarshal(yml, &bsn) + yml, _ := os.ReadFile("../../test_specs/first.yaml") + var bsn yaml.Node + _ = yaml.Unmarshal(yml, &bsn) - cf := index.CreateOpenAPIIndexConfig() - cf.BasePath = "../../test_specs" + cf := index.CreateOpenAPIIndexConfig() + cf.BasePath = "../../test_specs" - localFSConfig := &index.LocalFSConfig{ - BaseDirectory: cf.BasePath, - FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, - DirFS: os.DirFS(cf.BasePath), - } - localFs, _ := index.NewLocalFSWithConfig(localFSConfig) - rolo := index.NewRolodex(cf) - rolo.AddLocalFS(cf.BasePath, localFs) - rolo.SetRootNode(&bsn) - rolo.IndexTheRolodex() - idx := rolo.GetRootIndex() - loop := yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Value: "$ref", - }, - { - Kind: yaml.ScalarNode, - Value: "", - }, - }, - } + localFSConfig := &index.LocalFSConfig{ + BaseDirectory: cf.BasePath, + FileFilters: []string{"first.yaml", "second.yaml", "third.yaml", "fourth.yaml"}, + DirFS: os.DirFS(cf.BasePath), + } + localFs, _ := index.NewLocalFSWithConfig(localFSConfig) + rolo := index.NewRolodex(cf) + rolo.AddLocalFS(cf.BasePath, localFs) + rolo.SetRootNode(&bsn) + rolo.IndexTheRolodex() + idx := rolo.GetRootIndex() + loop := yaml.Node{ + Kind: yaml.MappingNode, + Content: []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Value: "$ref", + }, + { + Kind: yaml.ScalarNode, + Value: "", + }, + }, + } - wd, _ := os.Getwd() - cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) - ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) - n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) - assert.Nil(t, n) - assert.Nil(t, i) - assert.Error(t, e) - assert.Equal(t, "reference at line 0, column 0 is empty, it cannot be resolved", e.Error()) - assert.NotNil(t, c) + wd, _ := os.Getwd() + cp, _ := filepath.Abs(filepath.Join(wd, "../../test_specs/first.yaml")) + ctx := context.WithValue(context.Background(), index.CurrentPathKey, cp) + n, i, e, c := LocateRefEnd(ctx, &loop, idx, 0) + assert.Nil(t, n) + assert.Nil(t, i) + assert.Error(t, e) + assert.Equal(t, "reference at line 0, column 0 is empty, it cannot be resolved", e.Error()) + assert.NotNil(t, c) } func TestArray_NotRefNotArray(t *testing.T) { - yml := `` - var idxNode yaml.Node - mErr := yaml.Unmarshal([]byte(yml), &idxNode) - assert.NoError(t, mErr) - idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) + yml := `` + var idxNode yaml.Node + mErr := yaml.Unmarshal([]byte(yml), &idxNode) + assert.NoError(t, mErr) + idx := index.NewSpecIndexWithConfig(&idxNode, index.CreateClosedAPIIndexConfig()) - yml = `limes: + yml = `limes: not: array` - var cNode yaml.Node - e := yaml.Unmarshal([]byte(yml), &cNode) - assert.NoError(t, e) - things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) - assert.Error(t, err) - assert.Equal(t, err.Error(), "array build failed, input is not an array, line 2, column 3") - assert.Len(t, things, 0) + var cNode yaml.Node + e := yaml.Unmarshal([]byte(yml), &cNode) + assert.NoError(t, e) + things, _, _, err := ExtractArray[*test_noGood](context.Background(), "limes", cNode.Content[0], idx) + assert.Error(t, err) + assert.Equal(t, err.Error(), "array build failed, input is not an array, line 2, column 3") + assert.Len(t, things, 0) } func TestHashExtensions(t *testing.T) { - type args struct { - ext *orderedmap.Map[KeyReference[string], ValueReference[*yaml.Node]] - } - tests := []struct { - name string - args args - want []string - }{ - { - name: "empty", - args: args{ - ext: orderedmap.New[KeyReference[string], ValueReference[*yaml.Node]](), - }, - want: []string{}, - }, - { - name: "hashes extensions", - args: args{ - ext: orderedmap.ToOrderedMap(map[KeyReference[string]]ValueReference[*yaml.Node]{ - {Value: "x-burger"}: { - Value: utils.CreateStringNode("yummy"), - }, - {Value: "x-car"}: { - Value: utils.CreateStringNode("ford"), - }, - }), - }, - want: []string{ - "x-burger-2a296977a4572521773eb7e7773cc054fae3e8589511ce9bf90cec7dd93d016a", - "x-car-7d3aa6a5c79cdb0c2585daed714fa0936a18e6767b2dcc804992a90f6d0b8f5e", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - hash := HashExtensions(tt.args.ext) - assert.Equal(t, tt.want, hash) - }) - } + type args struct { + ext *orderedmap.Map[KeyReference[string], ValueReference[*yaml.Node]] + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "empty", + args: args{ + ext: orderedmap.New[KeyReference[string], ValueReference[*yaml.Node]](), + }, + want: []string{}, + }, + { + name: "hashes extensions", + args: args{ + ext: orderedmap.ToOrderedMap(map[KeyReference[string]]ValueReference[*yaml.Node]{ + {Value: "x-burger"}: { + Value: utils.CreateStringNode("yummy"), + }, + {Value: "x-car"}: { + Value: utils.CreateStringNode("ford"), + }, + }), + }, + want: []string{ + "x-burger-2a296977a4572521773eb7e7773cc054fae3e8589511ce9bf90cec7dd93d016a", + "x-car-7d3aa6a5c79cdb0c2585daed714fa0936a18e6767b2dcc804992a90f6d0b8f5e", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hash := HashExtensions(tt.args.ext) + assert.Equal(t, tt.want, hash) + }) + } } func TestValueToString(t *testing.T) { - type args struct { - v any - } - tests := []struct { - name string - args args - want string - }{ - { - name: "string", - args: args{ - v: "hello", - }, - want: "hello", - }, - { - name: "int", - args: args{ - v: 1, - }, - want: "1", - }, - { - name: "yaml.Node", - args: args{ - v: utils.CreateStringNode("world"), - }, - want: "world", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := ValueToString(tt.args.v) - assert.Equal(t, tt.want, strings.TrimSpace(got)) - }) - } + type args struct { + v any + } + tests := []struct { + name string + args args + want string + }{ + { + name: "string", + args: args{ + v: "hello", + }, + want: "hello", + }, + { + name: "int", + args: args{ + v: 1, + }, + want: "1", + }, + { + name: "yaml.Node", + args: args{ + v: utils.CreateStringNode("world"), + }, + want: "world", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := ValueToString(tt.args.v) + assert.Equal(t, tt.want, strings.TrimSpace(got)) + }) + } } diff --git a/index/rolodex_test.go b/index/rolodex_test.go index e7ded40..fbdab64 100644 --- a/index/rolodex_test.go +++ b/index/rolodex_test.go @@ -4,329 +4,329 @@ package index import ( - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" - "io" - "io/fs" - "log/slog" - "net/http" - "net/http/httptest" - "net/url" - "os" - "path/filepath" - "runtime" - "strings" - "testing" - "testing/fstest" - "time" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "io" + "io/fs" + "log/slog" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "testing/fstest" + "time" ) func TestRolodex_NewRolodex(t *testing.T) { - c := CreateOpenAPIIndexConfig() - rolo := NewRolodex(c) - assert.NotNil(t, rolo) - assert.NotNil(t, rolo.indexConfig) - assert.Nil(t, rolo.GetIgnoredCircularReferences()) - assert.Equal(t, rolo.GetIndexingDuration(), time.Duration(0)) - assert.Nil(t, rolo.GetRootIndex()) - assert.Len(t, rolo.GetIndexes(), 0) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateOpenAPIIndexConfig() + rolo := NewRolodex(c) + assert.NotNil(t, rolo) + assert.NotNil(t, rolo.indexConfig) + assert.Nil(t, rolo.GetIgnoredCircularReferences()) + assert.Equal(t, rolo.GetIndexingDuration(), time.Duration(0)) + assert.Nil(t, rolo.GetRootIndex()) + assert.Len(t, rolo.GetIndexes(), 0) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_NoFS(t *testing.T) { - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rf, err := rolo.Open("spec.yaml") - assert.Error(t, err) - assert.Equal(t, "rolodex has no file systems configured, cannot open 'spec.yaml'. "+ - "Add a BaseURL or BasePath to your configuration so the rolodex knows how to resolve references", err.Error()) - assert.Nil(t, rf) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rf, err := rolo.Open("spec.yaml") + assert.Error(t, err) + assert.Equal(t, "rolodex has no file systems configured, cannot open 'spec.yaml'. "+ + "Add a BaseURL or BasePath to your configuration so the rolodex knows how to resolve references", err.Error()) + assert.Nil(t, rf) } func TestRolodex_NoFSButHasRemoteFS(t *testing.T) { - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddRemoteFS("http://localhost", nil) - rf, err := rolo.Open("spec.yaml") - assert.Error(t, err) - assert.Equal(t, "the rolodex has no local file systems configured, cannot open local file 'spec.yaml'", err.Error()) - assert.Nil(t, rf) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddRemoteFS("http://localhost", nil) + rf, err := rolo.Open("spec.yaml") + assert.Error(t, err) + assert.Equal(t, "the rolodex has no local file systems configured, cannot open local file 'spec.yaml'", err.Error()) + assert.Nil(t, rf) } func TestRolodex_LocalNativeFS(t *testing.T) { - t.Parallel() - testFS := fstest.MapFS{ - "spec.yaml": {Data: []byte("hip"), ModTime: time.Now()}, - "subfolder/spec1.json": {Data: []byte("hop"), ModTime: time.Now()}, - "subfolder2/spec2.yaml": {Data: []byte("chop"), ModTime: time.Now()}, - "subfolder2/hello.jpg": {Data: []byte("shop"), ModTime: time.Now()}, - } + t.Parallel() + testFS := fstest.MapFS{ + "spec.yaml": {Data: []byte("hip"), ModTime: time.Now()}, + "subfolder/spec1.json": {Data: []byte("hop"), ModTime: time.Now()}, + "subfolder2/spec2.yaml": {Data: []byte("chop"), ModTime: time.Now()}, + "subfolder2/hello.jpg": {Data: []byte("shop"), ModTime: time.Now()}, + } - baseDir := "/tmp" + baseDir := "/tmp" - fileFS, err := NewLocalFSWithConfig(&LocalFSConfig{ - BaseDirectory: baseDir, - Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ - Level: slog.LevelDebug, - })), - DirFS: testFS, - }) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(&LocalFSConfig{ + BaseDirectory: baseDir, + Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelDebug, + })), + DirFS: testFS, + }) + if err != nil { + t.Fatal(err) + } - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddLocalFS(baseDir, fileFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddLocalFS(baseDir, fileFS) - f, rerr := rolo.Open("spec.yaml") - assert.NoError(t, rerr) - assert.Equal(t, "hip", f.GetContent()) + f, rerr := rolo.Open("spec.yaml") + assert.NoError(t, rerr) + assert.Equal(t, "hip", f.GetContent()) } func TestRolodex_LocalNonNativeFS(t *testing.T) { - t.Parallel() - testFS := fstest.MapFS{ - "spec.yaml": {Data: []byte("hip"), ModTime: time.Now()}, - "subfolder/spec1.json": {Data: []byte("hop"), ModTime: time.Now()}, - "subfolder2/spec2.yaml": {Data: []byte("chop"), ModTime: time.Now()}, - "subfolder2/hello.jpg": {Data: []byte("shop"), ModTime: time.Now()}, - } + t.Parallel() + testFS := fstest.MapFS{ + "spec.yaml": {Data: []byte("hip"), ModTime: time.Now()}, + "subfolder/spec1.json": {Data: []byte("hop"), ModTime: time.Now()}, + "subfolder2/spec2.yaml": {Data: []byte("chop"), ModTime: time.Now()}, + "subfolder2/hello.jpg": {Data: []byte("shop"), ModTime: time.Now()}, + } - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddLocalFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddLocalFS(baseDir, testFS) - f, rerr := rolo.Open("spec.yaml") - assert.NoError(t, rerr) + f, rerr := rolo.Open("spec.yaml") + assert.NoError(t, rerr) - assert.Equal(t, "hip", f.GetContent()) + assert.Equal(t, "hip", f.GetContent()) } type test_badfs struct { - ok bool - goodstat bool - offset int64 + ok bool + goodstat bool + offset int64 } func (t *test_badfs) Open(v string) (fs.File, error) { - ok := false - if v != "/" && v != "." && v != "http://localhost/test.yaml" { - ok = true - } - if v == "http://localhost/goodstat.yaml" || strings.HasSuffix(v, "goodstat.yaml") { - ok = true - t.goodstat = true - } - if v == "http://localhost/badstat.yaml" || v == "badstat.yaml" { - ok = true - t.goodstat = false - } - return &test_badfs{ok: ok, goodstat: t.goodstat}, nil + ok := false + if v != "/" && v != "." && v != "http://localhost/test.yaml" { + ok = true + } + if v == "http://localhost/goodstat.yaml" || strings.HasSuffix(v, "goodstat.yaml") { + ok = true + t.goodstat = true + } + if v == "http://localhost/badstat.yaml" || v == "badstat.yaml" { + ok = true + t.goodstat = false + } + return &test_badfs{ok: ok, goodstat: t.goodstat}, nil } func (t *test_badfs) Stat() (fs.FileInfo, error) { - if t.goodstat { - return &LocalFile{ - lastModified: time.Now(), - }, nil - } - return nil, os.ErrInvalid + if t.goodstat { + return &LocalFile{ + lastModified: time.Now(), + }, nil + } + return nil, os.ErrInvalid } func (t *test_badfs) Read(b []byte) (int, error) { - if t.ok { - if t.offset >= int64(len("pizza")) { - return 0, io.EOF - } - if t.offset < 0 { - return 0, &fs.PathError{Op: "read", Path: "lemons", Err: fs.ErrInvalid} - } - n := copy(b, "pizza"[t.offset:]) - t.offset += int64(n) - return n, nil - } - return 0, os.ErrNotExist + if t.ok { + if t.offset >= int64(len("pizza")) { + return 0, io.EOF + } + if t.offset < 0 { + return 0, &fs.PathError{Op: "read", Path: "lemons", Err: fs.ErrInvalid} + } + n := copy(b, "pizza"[t.offset:]) + t.offset += int64(n) + return n, nil + } + return 0, os.ErrNotExist } func (t *test_badfs) Close() error { - return os.ErrNotExist + return os.ErrNotExist } func TestRolodex_LocalNonNativeFS_BadRead(t *testing.T) { - t.Parallel() - testFS := &test_badfs{} + t.Parallel() + testFS := &test_badfs{} - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddLocalFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddLocalFS(baseDir, testFS) - f, rerr := rolo.Open("/") - assert.Nil(t, f) - assert.Error(t, rerr) - if runtime.GOOS != "windows" { - assert.Equal(t, "file does not exist", rerr.Error()) - } else { - assert.Equal(t, "invalid argument", rerr.Error()) - } + f, rerr := rolo.Open("/") + assert.Nil(t, f) + assert.Error(t, rerr) + if runtime.GOOS != "windows" { + assert.Equal(t, "file does not exist", rerr.Error()) + } else { + assert.Equal(t, "invalid argument", rerr.Error()) + } } func TestRolodex_LocalNonNativeFS_BadStat(t *testing.T) { - t.Parallel() - testFS := &test_badfs{} + t.Parallel() + testFS := &test_badfs{} - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddLocalFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddLocalFS(baseDir, testFS) - f, rerr := rolo.Open("badstat.yaml") - assert.Nil(t, f) - assert.Error(t, rerr) - assert.Equal(t, "invalid argument", rerr.Error()) + f, rerr := rolo.Open("badstat.yaml") + assert.Nil(t, f) + assert.Error(t, rerr) + assert.Equal(t, "invalid argument", rerr.Error()) } func TestRolodex_LocalNonNativeRemoteFS_BadRead(t *testing.T) { - t.Parallel() - testFS := &test_badfs{} + t.Parallel() + testFS := &test_badfs{} - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddRemoteFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddRemoteFS(baseDir, testFS) - f, rerr := rolo.Open("http://localhost/test.yaml") - assert.Nil(t, f) - assert.Error(t, rerr) - assert.Equal(t, "file does not exist", rerr.Error()) + f, rerr := rolo.Open("http://localhost/test.yaml") + assert.Nil(t, f) + assert.Error(t, rerr) + assert.Equal(t, "file does not exist", rerr.Error()) } func TestRolodex_LocalNonNativeRemoteFS_ReadFile(t *testing.T) { - t.Parallel() - testFS := &test_badfs{} + t.Parallel() + testFS := &test_badfs{} - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddRemoteFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddRemoteFS(baseDir, testFS) - r, rerr := rolo.Open("http://localhost/goodstat.yaml") - assert.NotNil(t, r) - assert.NoError(t, rerr) + r, rerr := rolo.Open("http://localhost/goodstat.yaml") + assert.NotNil(t, r) + assert.NoError(t, rerr) - assert.Equal(t, "goodstat.yaml", r.Name()) - assert.Nil(t, r.GetIndex()) - assert.Equal(t, "pizza", r.GetContent()) - assert.Equal(t, "http://localhost/goodstat.yaml", r.GetFullPath()) - assert.Greater(t, r.ModTime().UnixMilli(), int64(1)) - assert.Equal(t, int64(5), r.Size()) - assert.False(t, r.IsDir()) - assert.Nil(t, r.Sys()) - assert.Equal(t, r.Mode(), os.FileMode(0)) - n, e := r.GetContentAsYAMLNode() - assert.Len(t, r.GetErrors(), 0) - assert.NoError(t, e) - assert.NotNil(t, n) - assert.Equal(t, YAML, r.GetFileExtension()) + assert.Equal(t, "goodstat.yaml", r.Name()) + assert.Nil(t, r.GetIndex()) + assert.Equal(t, "pizza", r.GetContent()) + assert.Equal(t, "http://localhost/goodstat.yaml", r.GetFullPath()) + assert.Greater(t, r.ModTime().UnixMilli(), int64(1)) + assert.Equal(t, int64(5), r.Size()) + assert.False(t, r.IsDir()) + assert.Nil(t, r.Sys()) + assert.Equal(t, r.Mode(), os.FileMode(0)) + n, e := r.GetContentAsYAMLNode() + assert.Len(t, r.GetErrors(), 0) + assert.NoError(t, e) + assert.NotNil(t, n) + assert.Equal(t, YAML, r.GetFileExtension()) } func TestRolodex_LocalNonNativeRemoteFS_BadStat(t *testing.T) { - t.Parallel() - testFS := &test_badfs{} + t.Parallel() + testFS := &test_badfs{} - baseDir := "" + baseDir := "" - rolo := NewRolodex(CreateOpenAPIIndexConfig()) - rolo.AddRemoteFS(baseDir, testFS) + rolo := NewRolodex(CreateOpenAPIIndexConfig()) + rolo.AddRemoteFS(baseDir, testFS) - f, rerr := rolo.Open("http://localhost/badstat.yaml") - assert.Nil(t, f) - assert.Error(t, rerr) - assert.Equal(t, "invalid argument", rerr.Error()) + f, rerr := rolo.Open("http://localhost/badstat.yaml") + assert.Nil(t, f) + assert.Error(t, rerr) + assert.Equal(t, "invalid argument", rerr.Error()) } func TestRolodex_rolodexFileTests(t *testing.T) { - r := &rolodexFile{} - assert.Equal(t, "", r.Name()) - assert.Nil(t, r.GetIndex()) - assert.Equal(t, "", r.GetContent()) - assert.Equal(t, "", r.GetFullPath()) - assert.Equal(t, time.Now().UnixMilli(), r.ModTime().UnixMilli()) - assert.Equal(t, int64(0), r.Size()) - assert.False(t, r.IsDir()) - assert.Nil(t, r.Sys()) - assert.Equal(t, r.Mode(), os.FileMode(0)) - n, e := r.GetContentAsYAMLNode() - assert.Len(t, r.GetErrors(), 0) - assert.NoError(t, e) - assert.Nil(t, n) - assert.Equal(t, UNSUPPORTED, r.GetFileExtension()) + r := &rolodexFile{} + assert.Equal(t, "", r.Name()) + assert.Nil(t, r.GetIndex()) + assert.Equal(t, "", r.GetContent()) + assert.Equal(t, "", r.GetFullPath()) + assert.Equal(t, time.Now().UnixMilli(), r.ModTime().UnixMilli()) + assert.Equal(t, int64(0), r.Size()) + assert.False(t, r.IsDir()) + assert.Nil(t, r.Sys()) + assert.Equal(t, r.Mode(), os.FileMode(0)) + n, e := r.GetContentAsYAMLNode() + assert.Len(t, r.GetErrors(), 0) + assert.NoError(t, e) + assert.Nil(t, n) + assert.Equal(t, UNSUPPORTED, r.GetFileExtension()) } func TestRolodex_NotRolodexFS(t *testing.T) { - nonRoloFS := os.DirFS(".") - cf := CreateOpenAPIIndexConfig() - rolo := NewRolodex(cf) - rolo.AddLocalFS(".", nonRoloFS) + nonRoloFS := os.DirFS(".") + cf := CreateOpenAPIIndexConfig() + rolo := NewRolodex(cf) + rolo.AddLocalFS(".", nonRoloFS) - err := rolo.IndexTheRolodex() + err := rolo.IndexTheRolodex() - assert.Error(t, err) - assert.Equal(t, "rolodex file system is not a RolodexFS", err.Error()) + assert.Error(t, err) + assert.Equal(t, "rolodex file system is not a RolodexFS", err.Error()) } func TestRolodex_IndexCircularLookup(t *testing.T) { - offToOz := `openapi: 3.1.0 + offToOz := `openapi: 3.1.0 components: schemas: CircleTest: $ref: "../test_specs/circular-tests.yaml#/components/schemas/One"` - _ = os.WriteFile("off_to_oz.yaml", []byte(offToOz), 0644) - defer os.Remove("off_to_oz.yaml") + _ = os.WriteFile("off_to_oz.yaml", []byte(offToOz), 0644) + defer os.Remove("off_to_oz.yaml") - baseDir := "../" + baseDir := "../" - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - "off_to_oz.yaml", - "test_specs/circular-tests.yaml", - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + "off_to_oz.yaml", + "test_specs/circular-tests.yaml", + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - rolodex := NewRolodex(cf) - rolodex.AddLocalFS(baseDir, fileFS) - err = rolodex.IndexTheRolodex() - assert.Error(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 3) - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 0) + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + rolodex := NewRolodex(cf) + rolodex.AddLocalFS(baseDir, fileFS) + err = rolodex.IndexTheRolodex() + assert.Error(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 3) + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 0) } func TestRolodex_IndexCircularLookup_AroundWeGo(t *testing.T) { - there := `openapi: 3.1.0 + there := `openapi: 3.1.0 components: schemas: CircleTest: @@ -337,7 +337,7 @@ components: where: $ref: "back-again.yaml#/components/schemas/CircleTest/properties/muffins"` - backagain := `openapi: 3.1.0 + backagain := `openapi: 3.1.0 components: schemas: CircleTest: @@ -348,49 +348,49 @@ components: muffins: $ref: "there.yaml#/components/schemas/CircleTest"` - _ = os.WriteFile("there.yaml", []byte(there), 0644) - _ = os.WriteFile("back-again.yaml", []byte(backagain), 0644) - defer os.Remove("there.yaml") - defer os.Remove("back-again.yaml") + _ = os.WriteFile("there.yaml", []byte(there), 0644) + _ = os.WriteFile("back-again.yaml", []byte(backagain), 0644) + defer os.Remove("there.yaml") + defer os.Remove("back-again.yaml") - baseDir := "." + baseDir := "." - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - "there.yaml", - "back-again.yaml", - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + "there.yaml", + "back-again.yaml", + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - rolodex := NewRolodex(cf) - rolodex.AddLocalFS(baseDir, fileFS) - err = rolodex.IndexTheRolodex() - assert.Error(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 1) - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 0) + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + rolodex := NewRolodex(cf) + rolodex.AddLocalFS(baseDir, fileFS) + err = rolodex.IndexTheRolodex() + assert.Error(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 1) + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 0) } func TestRolodex_IndexCircularLookup_AroundWeGo_IgnorePoly(t *testing.T) { - fifth := "type: string" + fifth := "type: string" - fourth := `type: "object" + fourth := `type: "object" properties: name: type: "string" children: type: "object"` - third := `type: "object" + third := `type: "object" properties: name: $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4" @@ -411,7 +411,7 @@ properties: required: - children` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -429,7 +429,7 @@ components: - "children" ` - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -441,180 +441,189 @@ components: $ref: "$2#/components/schemas/CircleTest" ` - var firstFile, secondFile, thirdFile, fourthFile, fifthFile *os.File - var fErr error + var firstFile, secondFile, thirdFile, fourthFile, fifthFile *os.File + var fErr error - tmp := "tmp-a" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-a" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") - assert.NoError(t, fErr) + thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + assert.NoError(t, fErr) - fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") - assert.NoError(t, fErr) + fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") + assert.NoError(t, fErr) - fifthFile, fErr = os.CreateTemp(tmp, "*-fifth.yaml") - assert.NoError(t, fErr) + fifthFile, fErr = os.CreateTemp(tmp, "*-fifth.yaml") + assert.NoError(t, fErr) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") - third = strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())) - third = strings.ReplaceAll(third, "$_4", fourthFile.Name()) - third = strings.ReplaceAll(third, "$5", filepath.Base(fifthFile.Name())) - third = strings.ReplaceAll(third, "$_5", fifthFile.Name()) - third = strings.ReplaceAll(strings.ReplaceAll(third, "$2", secondFile.Name()), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") + third = strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())) + third = strings.ReplaceAll(third, "$_4", fourthFile.Name()) + third = strings.ReplaceAll(third, "$5", filepath.Base(fifthFile.Name())) + third = strings.ReplaceAll(third, "$_5", fifthFile.Name()) + third = strings.ReplaceAll(strings.ReplaceAll(third, "$2", secondFile.Name()), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) - thirdFile.WriteString(third) - fourthFile.WriteString(fourth) - fifthFile.WriteString(fifth) + firstFile.WriteString(first) + secondFile.WriteString(second) + thirdFile.WriteString(third) + fourthFile.WriteString(fourth) + fifthFile.WriteString(fifth) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - baseDir := "tmp-a" + baseDir := "tmp-a" - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - filepath.Base(thirdFile.Name()), - filepath.Base(fourthFile.Name()), - filepath.Base(fifthFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + filepath.Base(thirdFile.Name()), + filepath.Base(fourthFile.Name()), + filepath.Base(fifthFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - cf.IgnorePolymorphicCircularReferences = true - cf.SkipDocumentCheck = true + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + cf.IgnorePolymorphicCircularReferences = true + cf.SkipDocumentCheck = true - // add logger to config - cf.Logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ - Level: slog.LevelDebug, - })) + // add logger to config + cf.Logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelDebug, + })) - rolodex := NewRolodex(cf) - rolodex.AddLocalFS(baseDir, fileFS) + rolodex := NewRolodex(cf) + rolodex.AddLocalFS(baseDir, fileFS) - srv := test_rolodexDeepRefServer([]byte(first), []byte(second), - []byte(third), []byte(fourth), []byte(fifth)) - defer srv.Close() + srv := test_rolodexDeepRefServer([]byte(first), []byte(second), + []byte(third), []byte(fourth), []byte(fifth)) + defer srv.Close() - u, _ := url.Parse(srv.URL) - cf.BaseURL = u - remoteFS, rErr := NewRemoteFSWithConfig(cf) - assert.NoError(t, rErr) + u, _ := url.Parse(srv.URL) + cf.BaseURL = u + remoteFS, rErr := NewRemoteFSWithConfig(cf) + assert.NoError(t, rErr) - rolodex.AddRemoteFS(srv.URL, remoteFS) + rolodex.AddRemoteFS(srv.URL, remoteFS) - err = rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + err = rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - // there are two circles. Once when reading the journey from first.yaml, and then a second internal look in second.yaml - // the index won't find three, because by the time that 'three' has been read, it's already been indexed and the journey - // discovered. - assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1) + // there are two circles. Once when reading the journey from first.yaml, and then a second internal look in second.yaml + // the index won't find three, because by the time that 'three' has been read, it's already been indexed and the journey + // discovered. + assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1) - // extract a local file - n, _ := filepath.Abs(firstFile.Name()) - f, _ := rolodex.Open(n) - // index - x, y := f.(*rolodexFile).Index(cf) - assert.NotNil(t, x) - assert.NoError(t, y) + // extract a local file + n, _ := filepath.Abs(firstFile.Name()) + f, _ := rolodex.Open(n) + // index + x, y := f.(*rolodexFile).Index(cf) + assert.NotNil(t, x) + assert.NoError(t, y) - // re-index - x, y = f.(*rolodexFile).Index(cf) - assert.NotNil(t, x) - assert.NoError(t, y) + // re-index + x, y = f.(*rolodexFile).Index(cf) + assert.NotNil(t, x) + assert.NoError(t, y) - // extract a remote file - f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fourthFile.Name())) + // extract a remote file + f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fourthFile.Name())) - // index - x, y = f.(*rolodexFile).Index(cf) - assert.NotNil(t, x) - assert.NoError(t, y) + // index + x, y = f.(*rolodexFile).Index(cf) + assert.NotNil(t, x) + assert.NoError(t, y) - // re-index - x, y = f.(*rolodexFile).Index(cf) - assert.NotNil(t, x) - assert.NoError(t, y) + // re-index + x, y = f.(*rolodexFile).Index(cf) + assert.NotNil(t, x) + assert.NoError(t, y) - // extract another remote file - f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fifthFile.Name())) + // extract another remote file + f, _ = rolodex.Open("http://the-space-race-is-all-about-space-and-time-dot.com/" + filepath.Base(fifthFile.Name())) - //change cf to perform document check (which should fail) - cf.SkipDocumentCheck = false + //change cf to perform document check (which should fail) + cf.SkipDocumentCheck = false + + // index and fail + x, y = f.(*rolodexFile).Index(cf) + assert.Nil(t, x) + assert.Error(t, y) + + // file file that is not local, but is remote + f, _ = rolodex.Open("/bingo/jingo.yaml") + assert.NotNil(t, f) - // index and fail - x, y = f.(*rolodexFile).Index(cf) - assert.Nil(t, x) - assert.Error(t, y) } func test_rolodexDeepRefServer(a, b, c, d, e []byte) *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - rw.Header().Set("Last-Modified", "Wed, 21 Oct 2015 12:28:00 GMT") - if strings.HasSuffix(req.URL.String(), "-first.yaml") { - _, _ = rw.Write(a) - return - } - if strings.HasSuffix(req.URL.String(), "-second.yaml") { - _, _ = rw.Write(b) - return - } - if strings.HasSuffix(req.URL.String(), "-third.yaml") { - _, _ = rw.Write(c) - return - } - if strings.HasSuffix(req.URL.String(), "-fourth.yaml") { - _, _ = rw.Write(d) - return - } - if strings.HasSuffix(req.URL.String(), "-fifth.yaml") { - _, _ = rw.Write(e) - return - } - rw.WriteHeader(http.StatusInternalServerError) - rw.Write([]byte("500 - COMPUTAR SAYS NO!")) - })) + return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.Header().Set("Last-Modified", "Wed, 21 Oct 2015 12:28:00 GMT") + if strings.HasSuffix(req.URL.String(), "-first.yaml") { + _, _ = rw.Write(a) + return + } + if strings.HasSuffix(req.URL.String(), "-second.yaml") { + _, _ = rw.Write(b) + return + } + if strings.HasSuffix(req.URL.String(), "-third.yaml") { + _, _ = rw.Write(c) + return + } + if strings.HasSuffix(req.URL.String(), "-fourth.yaml") { + _, _ = rw.Write(d) + return + } + if strings.HasSuffix(req.URL.String(), "-fifth.yaml") { + _, _ = rw.Write(e) + return + } + if strings.HasSuffix(req.URL.String(), "/bingo/jingo.yaml") { + _, _ = rw.Write([]byte("openapi: 3.1.0")) + return + } + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte("500 - COMPUTAR SAYS NO!")) + })) } func TestRolodex_IndexCircularLookup_PolyItems_LocalLoop_WithFiles_RecursiveLookup(t *testing.T) { - fourth := `type: "object" + fourth := `type: "object" properties: name: type: "string" children: type: "object"` - third := `type: "object" + third := `type: "object" properties: herbs: $ref: "$1" name: $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4"` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -632,7 +641,7 @@ components: - "name" - "children"` - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -643,79 +652,79 @@ components: muffins: $ref: "$2#/components/schemas/CircleTest"` - var firstFile, secondFile, thirdFile, fourthFile *os.File - var fErr error + var firstFile, secondFile, thirdFile, fourthFile *os.File + var fErr error - tmp := "tmp-b" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-b" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") - assert.NoError(t, fErr) + thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + assert.NoError(t, fErr) - fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") - assert.NoError(t, fErr) + fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") - third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") - third = strings.ReplaceAll(strings.ReplaceAll(first, "$1", filepath.Base(firstFile.Name())), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") + third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") + third = strings.ReplaceAll(strings.ReplaceAll(first, "$1", filepath.Base(firstFile.Name())), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) - thirdFile.WriteString(third) - fourthFile.WriteString(fourth) + firstFile.WriteString(first) + secondFile.WriteString(second) + thirdFile.WriteString(third) + fourthFile.WriteString(fourth) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - baseDir := tmp - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - cf.IgnorePolymorphicCircularReferences = true + baseDir := tmp + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + cf.IgnorePolymorphicCircularReferences = true - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - IndexConfig: cf, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + IndexConfig: cf, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - rolodex := NewRolodex(cf) - rolodex.AddLocalFS(baseDir, fileFS) + rolodex := NewRolodex(cf) + rolodex.AddLocalFS(baseDir, fileFS) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) - rolodex.SetRootNode(&rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) + rolodex.SetRootNode(&rootNode) - srv := test_rolodexDeepRefServer([]byte(first), []byte(second), - []byte(third), []byte(fourth), nil) - defer srv.Close() + srv := test_rolodexDeepRefServer([]byte(first), []byte(second), + []byte(third), []byte(fourth), nil) + defer srv.Close() - u, _ := url.Parse(srv.URL) - cf.BaseURL = u - remoteFS, rErr := NewRemoteFSWithConfig(cf) - assert.NoError(t, rErr) + u, _ := url.Parse(srv.URL) + cf.BaseURL = u + remoteFS, rErr := NewRemoteFSWithConfig(cf) + assert.NoError(t, rErr) - rolodex.AddRemoteFS(srv.URL, remoteFS) + rolodex.AddRemoteFS(srv.URL, remoteFS) - err = rolodex.IndexTheRolodex() - assert.Error(t, err) - assert.GreaterOrEqual(t, len(rolodex.GetCaughtErrors()), 1) - assert.Equal(t, "cannot resolve reference `not_found.yaml`, it's missing: [8:11]", rolodex.GetCaughtErrors()[0].Error()) + err = rolodex.IndexTheRolodex() + assert.Error(t, err) + assert.GreaterOrEqual(t, len(rolodex.GetCaughtErrors()), 1) + assert.Equal(t, "cannot resolve reference `not_found.yaml`, it's missing: [8:11]", rolodex.GetCaughtErrors()[0].Error()) } func TestRolodex_IndexCircularLookup_PolyItems_LocalLoop_WithFiles(t *testing.T) { - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: CircleTest: @@ -741,7 +750,7 @@ components: anyOf: - $ref: "#/components/schemas/CircleTest"` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -767,63 +776,63 @@ components: anyOf: - $ref: "#/components/schemas/CircleTest"` - var firstFile, secondFile *os.File - var fErr error + var firstFile, secondFile *os.File + var fErr error - tmp := "tmp-f" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-f" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) + firstFile.WriteString(first) + secondFile.WriteString(second) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) - baseDir := tmp + baseDir := tmp - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - rolodex.AddLocalFS(baseDir, fileFS) - rolodex.SetRootNode(&rootNode) - assert.NotNil(t, rolodex.GetRootNode()) + rolodex.AddLocalFS(baseDir, fileFS) + rolodex.SetRootNode(&rootNode) + assert.NotNil(t, rolodex.GetRootNode()) - err = rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + err = rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - // multiple loops across two files - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + // multiple loops across two files + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) } func TestRolodex_IndexCircularLookup_PolyItems_LocalLoop_BuildIndexesPost(t *testing.T) { - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: CircleTest: @@ -849,7 +858,7 @@ components: anyOf: - $ref: "#/components/schemas/CircleTest"` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -875,70 +884,70 @@ components: anyOf: - $ref: "#/components/schemas/CircleTest"` - var firstFile, secondFile *os.File - var fErr error + var firstFile, secondFile *os.File + var fErr error - tmp := "tmp-c" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-c" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) + firstFile.WriteString(first) + secondFile.WriteString(second) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - cf.AvoidBuildIndex = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + cf.AvoidBuildIndex = true + rolodex := NewRolodex(cf) - baseDir := tmp + baseDir := tmp - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - rolodex.AddLocalFS(baseDir, fileFS) - rolodex.SetRootNode(&rootNode) + rolodex.AddLocalFS(baseDir, fileFS) + rolodex.SetRootNode(&rootNode) - err = rolodex.IndexTheRolodex() - rolodex.BuildIndexes() + err = rolodex.IndexTheRolodex() + rolodex.BuildIndexes() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - // multiple loops across two files - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + // multiple loops across two files + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) - // trigger a rebuild, should do nothing. - rolodex.BuildIndexes() - assert.Len(t, rolodex.GetCaughtErrors(), 0) + // trigger a rebuild, should do nothing. + rolodex.BuildIndexes() + assert.Len(t, rolodex.GetCaughtErrors(), 0) } func TestRolodex_IndexCircularLookup_ArrayItems_LocalLoop_WithFiles(t *testing.T) { - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: CircleTest: @@ -963,7 +972,7 @@ components: items: $ref: "#/components/schemas/CircleTest"` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -988,68 +997,68 @@ components: items: $ref: "#/components/schemas/CircleTest"` - var firstFile, secondFile *os.File - var fErr error + var firstFile, secondFile *os.File + var fErr error - tmp := "tmp-d" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-d" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) + firstFile.WriteString(first) + secondFile.WriteString(second) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnoreArrayCircularReferences = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnoreArrayCircularReferences = true + rolodex := NewRolodex(cf) - baseDir := tmp + baseDir := tmp - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - rolodex.AddLocalFS(baseDir, fileFS) - rolodex.SetRootNode(&rootNode) + rolodex.AddLocalFS(baseDir, fileFS) + rolodex.SetRootNode(&rootNode) - err = rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + err = rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - // multiple loops across two files - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + // multiple loops across two files + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) } func TestRolodex_IndexCircularLookup_PolyItemsHttpOnly(t *testing.T) { - third := `type: string` - fourth := `components: + third := `type: string` + fourth := `components: schemas: Chicken: type: string` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: Loopy: @@ -1097,7 +1106,7 @@ components: - "name" - "children"` - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -1119,70 +1128,70 @@ components: - $ref: "https://where-are-all-my-jellies.com/$2#/components/schemas/CircleTest" ` - var firstFile, secondFile, thirdFile, fourthFile *os.File - var fErr error + var firstFile, secondFile, thirdFile, fourthFile *os.File + var fErr error - tmp := "tmp-e" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-e" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") - assert.NoError(t, fErr) + thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + assert.NoError(t, fErr) - fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") - assert.NoError(t, fErr) + fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(first, "$2", filepath.Base(secondFile.Name())) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", filepath.Base(thirdFile.Name())), "\\", "\\\\") + first = strings.ReplaceAll(first, "$2", filepath.Base(secondFile.Name())) + first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", filepath.Base(thirdFile.Name())), "\\", "\\\\") - second = strings.ReplaceAll(second, "$3", filepath.Base(thirdFile.Name())) - second = strings.ReplaceAll(second, "$1", filepath.Base(firstFile.Name())) - second = strings.ReplaceAll(strings.ReplaceAll(second, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") + second = strings.ReplaceAll(second, "$3", filepath.Base(thirdFile.Name())) + second = strings.ReplaceAll(second, "$1", filepath.Base(firstFile.Name())) + second = strings.ReplaceAll(strings.ReplaceAll(second, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) - thirdFile.WriteString(third) - fourthFile.WriteString(fourth) + firstFile.WriteString(first) + secondFile.WriteString(second) + thirdFile.WriteString(third) + fourthFile.WriteString(fourth) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) - srv := test_rolodexDeepRefServer([]byte(first), []byte(second), []byte(third), []byte(fourth), nil) - defer srv.Close() + srv := test_rolodexDeepRefServer([]byte(first), []byte(second), []byte(third), []byte(fourth), nil) + defer srv.Close() - u, _ := url.Parse(srv.URL) - cf.BaseURL = u - remoteFS, rErr := NewRemoteFSWithConfig(cf) - assert.NoError(t, rErr) + u, _ := url.Parse(srv.URL) + cf.BaseURL = u + remoteFS, rErr := NewRemoteFSWithConfig(cf) + assert.NoError(t, rErr) - rolodex.AddRemoteFS(srv.URL, remoteFS) - rolodex.SetRootNode(&rootNode) + rolodex.AddRemoteFS(srv.URL, remoteFS) + rolodex.SetRootNode(&rootNode) - err := rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + err := rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1) - assert.Equal(t, rolodex.GetRootIndex().GetResolver().GetIndexesVisited(), 11) + assert.GreaterOrEqual(t, len(rolodex.GetIgnoredCircularReferences()), 1) + assert.Equal(t, rolodex.GetRootIndex().GetResolver().GetIndexesVisited(), 11) } func TestRolodex_IndexCircularLookup_PolyItemsFileOnly_LocalIncluded(t *testing.T) { - third := `type: string` + third := `type: string` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: LoopyMcLoopFace: @@ -1216,7 +1225,7 @@ components: - "name" - "children"` - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -1230,81 +1239,81 @@ components: - $ref: "$2#/components/schemas/CircleTest" - $ref: "$3"` - var firstFile, secondFile, thirdFile *os.File - var fErr error + var firstFile, secondFile, thirdFile *os.File + var fErr error - tmp := "tmp-g" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-g" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") - assert.NoError(t, fErr) + thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(first, "$2", secondFile.Name()) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", thirdFile.Name()), "\\", "\\\\") - second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") + first = strings.ReplaceAll(first, "$2", secondFile.Name()) + first = strings.ReplaceAll(strings.ReplaceAll(first, "$3", thirdFile.Name()), "\\", "\\\\") + second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) - thirdFile.WriteString(third) + firstFile.WriteString(first) + secondFile.WriteString(second) + thirdFile.WriteString(third) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) - baseDir := tmp + baseDir := tmp - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - filepath.Base(thirdFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + filepath.Base(thirdFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - rolodex.AddLocalFS(baseDir, fileFS) - rolodex.SetRootNode(&rootNode) + rolodex.AddLocalFS(baseDir, fileFS) + rolodex.SetRootNode(&rootNode) - err = rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) + err = rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) - // should only be a single loop. - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + // should only be a single loop. + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) } func TestRolodex_TestDropDownToRemoteFS_CatchErrors(t *testing.T) { - fourth := `type: "object" + fourth := `type: "object" properties: name: type: "string" children: type: "object"` - third := `type: "object" + third := `type: "object" properties: name: $ref: "http://the-space-race-is-all-about-space-and-time-dot.com/$4"` - second := `openapi: 3.1.0 + second := `openapi: 3.1.0 components: schemas: CircleTest: @@ -1322,7 +1331,7 @@ components: - "name" - "children"` - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -1333,79 +1342,79 @@ components: muffins: $ref: "$2#/components/schemas/CircleTest"` - var firstFile, secondFile, thirdFile, fourthFile *os.File - var fErr error + var firstFile, secondFile, thirdFile, fourthFile *os.File + var fErr error - tmp := "tmp-h" - _ = os.Mkdir(tmp, 0755) + tmp := "tmp-h" + _ = os.Mkdir(tmp, 0755) - firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") - assert.NoError(t, fErr) + firstFile, fErr = os.CreateTemp(tmp, "*-first.yaml") + assert.NoError(t, fErr) - secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") - assert.NoError(t, fErr) + secondFile, fErr = os.CreateTemp(tmp, "*-second.yaml") + assert.NoError(t, fErr) - thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") - assert.NoError(t, fErr) + thirdFile, fErr = os.CreateTemp(tmp, "*-third.yaml") + assert.NoError(t, fErr) - fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") - assert.NoError(t, fErr) + fourthFile, fErr = os.CreateTemp(tmp, "*-fourth.yaml") + assert.NoError(t, fErr) - first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") - second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") - third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") + first = strings.ReplaceAll(strings.ReplaceAll(first, "$2", secondFile.Name()), "\\", "\\\\") + second = strings.ReplaceAll(strings.ReplaceAll(second, "$3", thirdFile.Name()), "\\", "\\\\") + third = strings.ReplaceAll(strings.ReplaceAll(third, "$4", filepath.Base(fourthFile.Name())), "\\", "\\\\") - firstFile.WriteString(first) - secondFile.WriteString(second) - thirdFile.WriteString(third) - fourthFile.WriteString(fourth) + firstFile.WriteString(first) + secondFile.WriteString(second) + thirdFile.WriteString(third) + fourthFile.WriteString(fourth) - defer os.RemoveAll(tmp) + defer os.RemoveAll(tmp) - baseDir := tmp + baseDir := tmp - fsCfg := &LocalFSConfig{ - BaseDirectory: baseDir, - DirFS: os.DirFS(baseDir), - FileFilters: []string{ - filepath.Base(firstFile.Name()), - filepath.Base(secondFile.Name()), - filepath.Base(thirdFile.Name()), - filepath.Base(fourthFile.Name()), - }, - } + fsCfg := &LocalFSConfig{ + BaseDirectory: baseDir, + DirFS: os.DirFS(baseDir), + FileFilters: []string{ + filepath.Base(firstFile.Name()), + filepath.Base(secondFile.Name()), + filepath.Base(thirdFile.Name()), + filepath.Base(fourthFile.Name()), + }, + } - fileFS, err := NewLocalFSWithConfig(fsCfg) - if err != nil { - t.Fatal(err) - } + fileFS, err := NewLocalFSWithConfig(fsCfg) + if err != nil { + t.Fatal(err) + } - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) - rolodex.AddLocalFS(baseDir, fileFS) + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) + rolodex.AddLocalFS(baseDir, fileFS) - srv := test_rolodexDeepRefServer([]byte(first), []byte(second), - []byte(third), []byte(fourth), nil) - defer srv.Close() + srv := test_rolodexDeepRefServer([]byte(first), []byte(second), + []byte(third), []byte(fourth), nil) + defer srv.Close() - u, _ := url.Parse(srv.URL) - cf.BaseURL = u - remoteFS, rErr := NewRemoteFSWithConfig(cf) - assert.NoError(t, rErr) + u, _ := url.Parse(srv.URL) + cf.BaseURL = u + remoteFS, rErr := NewRemoteFSWithConfig(cf) + assert.NoError(t, rErr) - rolodex.AddRemoteFS(srv.URL, remoteFS) + rolodex.AddRemoteFS(srv.URL, remoteFS) - err = rolodex.IndexTheRolodex() - assert.Error(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 2) - assert.Equal(t, "cannot resolve reference `not_found.yaml`, it's missing: [8:11]", rolodex.GetCaughtErrors()[0].Error()) + err = rolodex.IndexTheRolodex() + assert.Error(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 2) + assert.Equal(t, "cannot resolve reference `not_found.yaml`, it's missing: [8:11]", rolodex.GetCaughtErrors()[0].Error()) } func TestRolodex_IndexCircularLookup_LookupHttpNoBaseURL(t *testing.T) { - first := `openapi: 3.1.0 + first := `openapi: 3.1.0 components: schemas: StartTest: @@ -1418,27 +1427,27 @@ components: anyOf: - $ref: "https://raw.githubusercontent.com/pb33f/libopenapi/main/test_specs/circular-tests.yaml#/components/schemas/One"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(first), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(first), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) - remoteFS, rErr := NewRemoteFSWithConfig(cf) - assert.NoError(t, rErr) + remoteFS, rErr := NewRemoteFSWithConfig(cf) + assert.NoError(t, rErr) - rolodex.AddRemoteFS("", remoteFS) - rolodex.SetRootNode(&rootNode) + rolodex.AddRemoteFS("", remoteFS) + rolodex.SetRootNode(&rootNode) - err := rolodex.IndexTheRolodex() - assert.Error(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 1) + err := rolodex.IndexTheRolodex() + assert.Error(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 1) } func TestRolodex_IndexCircularLookup_ignorePoly(t *testing.T) { - spinny := `openapi: 3.1.0 + spinny := `openapi: 3.1.0 components: schemas: ProductCategory: @@ -1455,22 +1464,22 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(spinny), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(spinny), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnorePolymorphicCircularReferences = true - rolodex := NewRolodex(cf) - rolodex.SetRootNode(&rootNode) - err := rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + cf := CreateOpenAPIIndexConfig() + cf.IgnorePolymorphicCircularReferences = true + rolodex := NewRolodex(cf) + rolodex.SetRootNode(&rootNode) + err := rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) } func TestRolodex_IndexCircularLookup_ignoreArray(t *testing.T) { - spinny := `openapi: 3.1.0 + spinny := `openapi: 3.1.0 components: schemas: ProductCategory: @@ -1487,87 +1496,87 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(spinny), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(spinny), &rootNode) - cf := CreateOpenAPIIndexConfig() - cf.IgnoreArrayCircularReferences = true - rolodex := NewRolodex(cf) - rolodex.SetRootNode(&rootNode) - err := rolodex.IndexTheRolodex() - assert.NoError(t, err) - assert.Len(t, rolodex.GetCaughtErrors(), 0) - assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) + cf := CreateOpenAPIIndexConfig() + cf.IgnoreArrayCircularReferences = true + rolodex := NewRolodex(cf) + rolodex.SetRootNode(&rootNode) + err := rolodex.IndexTheRolodex() + assert.NoError(t, err) + assert.Len(t, rolodex.GetCaughtErrors(), 0) + assert.Len(t, rolodex.GetIgnoredCircularReferences(), 1) } func TestRolodex_SimpleTest_OneDoc(t *testing.T) { - baseDir := "rolodex_test_data" + baseDir := "rolodex_test_data" - fileFS, err := NewLocalFSWithConfig(&LocalFSConfig{ - BaseDirectory: baseDir, - Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ - Level: slog.LevelDebug, - })), - DirFS: os.DirFS(baseDir), - }) + fileFS, err := NewLocalFSWithConfig(&LocalFSConfig{ + BaseDirectory: baseDir, + Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelDebug, + })), + DirFS: os.DirFS(baseDir), + }) - if err != nil { - t.Fatal(err) - } + if err != nil { + t.Fatal(err) + } - cf := CreateOpenAPIIndexConfig() - cf.BasePath = baseDir - cf.IgnoreArrayCircularReferences = true - cf.IgnorePolymorphicCircularReferences = true + cf := CreateOpenAPIIndexConfig() + cf.BasePath = baseDir + cf.IgnoreArrayCircularReferences = true + cf.IgnorePolymorphicCircularReferences = true - rolo := NewRolodex(cf) - rolo.AddLocalFS(baseDir, fileFS) + rolo := NewRolodex(cf) + rolo.AddLocalFS(baseDir, fileFS) - err = rolo.IndexTheRolodex() + err = rolo.IndexTheRolodex() - //assert.NotZero(t, rolo.GetIndexingDuration()) comes back as 0 on windows. - assert.Nil(t, rolo.GetRootIndex()) - assert.Len(t, rolo.GetIndexes(), 9) + //assert.NotZero(t, rolo.GetIndexingDuration()) comes back as 0 on windows. + assert.Nil(t, rolo.GetRootIndex()) + assert.Len(t, rolo.GetIndexes(), 9) - assert.NoError(t, err) - assert.Len(t, rolo.indexes, 9) + assert.NoError(t, err) + assert.Len(t, rolo.indexes, 9) - // open components.yaml - f, rerr := rolo.Open("components.yaml") - assert.NoError(t, rerr) - assert.Equal(t, "components.yaml", f.Name()) + // open components.yaml + f, rerr := rolo.Open("components.yaml") + assert.NoError(t, rerr) + assert.Equal(t, "components.yaml", f.Name()) - idx, ierr := f.(*rolodexFile).Index(cf) - assert.NoError(t, ierr) - assert.NotNil(t, idx) - assert.Equal(t, YAML, f.GetFileExtension()) - assert.True(t, strings.HasSuffix(f.GetFullPath(), "rolodex_test_data"+string(os.PathSeparator)+"components.yaml")) - assert.NotNil(t, f.ModTime()) - if runtime.GOOS != "windows" { - assert.Equal(t, int64(283), f.Size()) - } else { - assert.Equal(t, int64(295), f.Size()) + idx, ierr := f.(*rolodexFile).Index(cf) + assert.NoError(t, ierr) + assert.NotNil(t, idx) + assert.Equal(t, YAML, f.GetFileExtension()) + assert.True(t, strings.HasSuffix(f.GetFullPath(), "rolodex_test_data"+string(os.PathSeparator)+"components.yaml")) + assert.NotNil(t, f.ModTime()) + if runtime.GOOS != "windows" { + assert.Equal(t, int64(283), f.Size()) + } else { + assert.Equal(t, int64(295), f.Size()) - } - assert.False(t, f.IsDir()) - assert.Nil(t, f.Sys()) - assert.Equal(t, fs.FileMode(0), f.Mode()) - assert.Len(t, f.GetErrors(), 0) + } + assert.False(t, f.IsDir()) + assert.Nil(t, f.Sys()) + assert.Equal(t, fs.FileMode(0), f.Mode()) + assert.Len(t, f.GetErrors(), 0) - // check the index has a rolodex reference - assert.NotNil(t, idx.GetRolodex()) + // check the index has a rolodex reference + assert.NotNil(t, idx.GetRolodex()) - // re-run the index should be a no-op - assert.NoError(t, rolo.IndexTheRolodex()) - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) + // re-run the index should be a no-op + assert.NoError(t, rolo.IndexTheRolodex()) + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) } func TestRolodex_CircularReferencesPolyIgnored(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: bingo: @@ -1591,24 +1600,24 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnorePolymorphicCircularReferences = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - assert.NotNil(t, rolo.GetRootIndex()) - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnorePolymorphicCircularReferences = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + assert.NotNil(t, rolo.GetRootIndex()) + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_CircularReferencesPolyIgnored_PostCheck(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: bingo: @@ -1632,25 +1641,25 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnorePolymorphicCircularReferences = true - c.AvoidCircularReferenceCheck = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - assert.NotNil(t, rolo.GetRootIndex()) - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnorePolymorphicCircularReferences = true + c.AvoidCircularReferenceCheck = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + assert.NotNil(t, rolo.GetRootIndex()) + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_CircularReferencesPolyIgnored_Resolve(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: bingo: @@ -1674,25 +1683,25 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnorePolymorphicCircularReferences = true - c.AvoidCircularReferenceCheck = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - assert.NotNil(t, rolo.GetRootIndex()) - rolo.Resolve() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnorePolymorphicCircularReferences = true + c.AvoidCircularReferenceCheck = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + assert.NotNil(t, rolo.GetRootIndex()) + rolo.Resolve() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_CircularReferencesPostCheck(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: bingo: @@ -1703,26 +1712,26 @@ components: required: - bango` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.AvoidCircularReferenceCheck = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - assert.NotNil(t, rolo.GetRootIndex()) - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) - assert.Len(t, rolo.GetCaughtErrors(), 1) - assert.Len(t, rolo.GetRootIndex().GetResolver().GetInfiniteCircularReferences(), 1) - assert.Len(t, rolo.GetRootIndex().GetResolver().GetSafeCircularReferences(), 0) + c := CreateClosedAPIIndexConfig() + c.AvoidCircularReferenceCheck = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + assert.NotNil(t, rolo.GetRootIndex()) + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 0) + assert.Len(t, rolo.GetCaughtErrors(), 1) + assert.Len(t, rolo.GetRootIndex().GetResolver().GetInfiniteCircularReferences(), 1) + assert.Len(t, rolo.GetRootIndex().GetResolver().GetSafeCircularReferences(), 0) } func TestRolodex_CircularReferencesArrayIgnored(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: ProductCategory: @@ -1739,23 +1748,23 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnoreArrayCircularReferences = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnoreArrayCircularReferences = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_CircularReferencesArrayIgnored_Resolve(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: ProductCategory: @@ -1772,23 +1781,23 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnoreArrayCircularReferences = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - rolo.Resolve() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnoreArrayCircularReferences = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + rolo.Resolve() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestRolodex_CircularReferencesArrayIgnored_PostCheck(t *testing.T) { - var d = `openapi: 3.1.0 + var d = `openapi: 3.1.0 components: schemas: ProductCategory: @@ -1805,26 +1814,26 @@ components: - "name" - "children"` - var rootNode yaml.Node - _ = yaml.Unmarshal([]byte(d), &rootNode) + var rootNode yaml.Node + _ = yaml.Unmarshal([]byte(d), &rootNode) - c := CreateClosedAPIIndexConfig() - c.IgnoreArrayCircularReferences = true - c.AvoidCircularReferenceCheck = true - rolo := NewRolodex(c) - rolo.SetRootNode(&rootNode) - _ = rolo.IndexTheRolodex() - rolo.CheckForCircularReferences() - assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) - assert.Len(t, rolo.GetCaughtErrors(), 0) + c := CreateClosedAPIIndexConfig() + c.IgnoreArrayCircularReferences = true + c.AvoidCircularReferenceCheck = true + rolo := NewRolodex(c) + rolo.SetRootNode(&rootNode) + _ = rolo.IndexTheRolodex() + rolo.CheckForCircularReferences() + assert.Len(t, rolo.GetIgnoredCircularReferences(), 1) + assert.Len(t, rolo.GetCaughtErrors(), 0) } func TestHumanFileSize(t *testing.T) { - // test bytes for different units - assert.Equal(t, "1 B", HumanFileSize(1)) - assert.Equal(t, "1 KB", HumanFileSize(1024)) - assert.Equal(t, "1 MB", HumanFileSize(1024*1024)) + // test bytes for different units + assert.Equal(t, "1 B", HumanFileSize(1)) + assert.Equal(t, "1 KB", HumanFileSize(1024)) + assert.Equal(t, "1 MB", HumanFileSize(1024*1024)) }