Skip to content

Commit

Permalink
tests: added unit tests to the internal packages
Browse files Browse the repository at this point in the history
This recovers a bit of the loss of test coverage ratio after accounting
for all source files.

Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
  • Loading branch information
fredbi committed Dec 26, 2023
1 parent e84721e commit c406152
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 32 deletions.
16 changes: 16 additions & 0 deletions fixtures/errors/fixture-unexpandable-2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ paths:
description: OK
schema:
$ref: '#/thisIs/anAbitrary/jsonPointer/toNowhere'
/wrong:
get:
operationId: target type mismatch
responses:
'200':
description: OK
schema:
$ref: '#/parameters/someWhere'
/wrongcode:
get:
operationId: target type mismatch
responses:
'two-hundred':
description: OK
schema:
type: string
definitions:
somePlace:
type: string
14 changes: 7 additions & 7 deletions flatten_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,13 +863,13 @@ func TestOperationIDs(t *testing.T) {
an := New(sp)
require.NoError(t, Flatten(FlattenOpts{Spec: an, BasePath: bp, Verbose: false, Minimal: false, RemoveUnused: false}))

res := operations.GatherOperations(New(sp), []string{"getSomeWhere", "getSomeWhereElse"})
_, ok := res["getSomeWhere"]
assert.Truef(t, ok, "Expected to find operation")
_, ok = res["getSomeWhereElse"]
assert.Truef(t, ok, "Expected to find operation")
_, ok = res["postSomeWhere"]
assert.Falsef(t, ok, "Did not expect to find operation")
t.Run("should GatherOperations", func(t *testing.T) {
res := operations.GatherOperations(New(sp), []string{"getSomeWhere", "getSomeWhereElse"})

assert.Containsf(t, res, "getSomeWhere", "expected to find operation")
assert.Containsf(t, res, "getSomeWhereElse", "expected to find operation")
assert.NotContainsf(t, res, "postSomeWhere", "did not expect to find operation")
})

op, ok := an.OperationFor("GET", "/some/where/else")
assert.True(t, ok)
Expand Down
4 changes: 2 additions & 2 deletions internal/antest/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ func initPathLoader() {
}
}

// LoadSpec loads a json a yaml spec
// LoadSpec loads a json or a yaml spec
func LoadSpec(path string) (*spec.Swagger, error) {
oncePathLoader.Do(initPathLoader)

data, err := swag.YAMLDoc(path)
data, err := spec.PathLoader(path)
if err != nil {
return nil, err
}
Expand Down
104 changes: 104 additions & 0 deletions internal/antest/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package antest

import (
"os"
"testing"

"github.com/stretchr/testify/require"
)

func TestLongTestEnabled(t *testing.T) {
t.Run("should be false by default", func(t *testing.T) {
require.False(t, LongTestsEnabled())
})
}

func TestLoadSpecErrorCases(t *testing.T) {
t.Run("should not load invalid path", func(t *testing.T) {
_, err := LoadSpec("nowhere.json")
require.Error(t, err)
})

t.Run("should not load invalid YAML", func(t *testing.T) {
invalidYAMLFile, clean := prepareBadDoc(t, "yaml", true)
t.Cleanup(clean)

_, err := LoadSpec(invalidYAMLFile)
require.Error(t, err)
})

t.Run("should not load invalid JSON", func(t *testing.T) {
invalidJSONFile, clean := prepareBadDoc(t, "json", true)
t.Cleanup(clean)

_, err := LoadSpec(invalidJSONFile)
require.Error(t, err)
})

t.Run("should not load invalid spec", func(t *testing.T) {
invalidJSONFile, clean := prepareBadDoc(t, "json", false)
t.Cleanup(clean)

_, err := LoadSpec(invalidJSONFile)
require.Error(t, err)
})
}

func prepareBadDoc(t testing.TB, kind string, invalidFormat bool) (string, func()) {
t.Helper()

var (
file string
data []byte
)

switch kind {
case "yaml", "yml":
f, err := os.CreateTemp("", "*.yaml")
require.NoError(t, err)
file = f.Name()

if invalidFormat {
data = []byte(`--
zig:
zag 3, 4
`)
} else {
data = []byte(`--
swagger: 2
info:
title: true
`)
}

case "json":
f, err := os.CreateTemp("", "*.json")
require.NoError(t, err)
file = f.Name()

if invalidFormat {
data = []byte(`{
"zig": {
"zag"
}`)
} else {
data = []byte(`{
"swagger": 2
"info": {
"title": true
}
}`)
}

default:
panic("supports only yaml or json")
}

require.NoError(t,
os.WriteFile(file, data, 0600),
)

return file, func() {
_ = os.RemoveAll(file)
}
}
62 changes: 62 additions & 0 deletions internal/flatten/operations/operations_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,67 @@
package operations

import (
"testing"

_ "github.com/go-openapi/analysis/internal/antest"
"github.com/go-openapi/spec"
"github.com/stretchr/testify/require"
)

var _ Provider = mockOperationsProvider{}

type mockOperationsProvider struct {
give map[string]map[string]*spec.Operation
}

func (m mockOperationsProvider) Operations() map[string]map[string]*spec.Operation {
return m.give
}

func TestGatherOperations(t *testing.T) {
t.Run("should handle empty operation IDs", func(_ *testing.T) {
m := mockOperationsProvider{
give: map[string]map[string]*spec.Operation{
"get": {
"/pth1": {
OperationProps: spec.OperationProps{
ID: "",
Description: "ok",
},
},
},
},
}

res := GatherOperations(m, nil)
require.Contains(t, res, "GetPth1")
})

t.Run("should handle duplicate operation IDs (when spec validation is skipped)", func(_ *testing.T) {
m := mockOperationsProvider{
give: map[string]map[string]*spec.Operation{
"get": {
"/pth1": {
OperationProps: spec.OperationProps{
ID: "id1",
Description: "ok",
},
},
},
"post": {
"/pth2": {
OperationProps: spec.OperationProps{
ID: "id1",
Description: "ok",
},
},
},
},
}

res := GatherOperations(m, nil)
require.Contains(t, res, "id1")
require.NotContains(t, res, "GetPth1")
require.Contains(t, res, "PostPth2")
})
}
77 changes: 54 additions & 23 deletions internal/flatten/replace/replace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,64 @@ func TestRewriteSchemaRef(t *testing.T) {
}
}

//nolint:dogsled
func TestReplace_ErrorHandling(t *testing.T) {
t.Parallel()

const wantedFailure = "Expected a failure"
const wantedFailure = "expected a failure"
bp := filepath.Join("..", "..", "..", "fixtures", "errors", "fixture-unexpandable-2.yaml")

// reload original spec
sp := antest.LoadOrFail(t, bp)

require.Errorf(t, RewriteSchemaToRef(sp, "#/invalidPointer/key", spec.Ref{}), wantedFailure)

require.Errorf(t, rewriteParentRef(sp, "#/invalidPointer/key", spec.Ref{}), wantedFailure)

require.Errorf(t, UpdateRef(sp, "#/invalidPointer/key", spec.Ref{}), wantedFailure)

require.Errorf(t, UpdateRefWithSchema(sp, "#/invalidPointer/key", &spec.Schema{}), wantedFailure)

_, _, err := getPointerFromKey(sp, "#/invalidPointer/key")
require.Errorf(t, err, wantedFailure)

_, _, err = getPointerFromKey(sp, "--->#/invalidJsonPointer")
require.Errorf(t, err, wantedFailure)

_, _, _, err = getParentFromKey(sp, "#/invalidPointer/key")
require.Errorf(t, err, wantedFailure)

_, _, _, err = getParentFromKey(sp, "--->#/invalidJsonPointer")
require.Errorf(t, err, wantedFailure)
t.Run("with invalid $ref", func(t *testing.T) {
const ref = "#/invalidPointer/key"

require.Errorf(t, RewriteSchemaToRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, rewriteParentRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, UpdateRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, UpdateRefWithSchema(sp, ref, &spec.Schema{}), wantedFailure)
_, _, err := getPointerFromKey(sp, ref)
require.Errorf(t, err, wantedFailure)

_, _, _, err = getParentFromKey(sp, ref)
require.Errorf(t, err, wantedFailure)
})

t.Run("with invalid jsonpointer formatting", func(t *testing.T) {
const pointer = "-->#/invalidJsonPointer"

_, _, err := getPointerFromKey(sp, pointer)
require.Errorf(t, err, wantedFailure)

_, _, _, err = getParentFromKey(sp, pointer)
require.Errorf(t, err, wantedFailure)
})

t.Run("with invalid target", func(t *testing.T) {
require.Errorf(t, RewriteSchemaToRef(sp, "#/parameters/someWhere", spec.Ref{}), wantedFailure)
})

t.Run("with invalid response target", func(t *testing.T) {
const ref = "#/paths/~1wrong/get/responses/200"
require.Errorf(t, RewriteSchemaToRef(sp, ref, spec.Ref{}), wantedFailure)
})

t.Run("with invalid response code", func(t *testing.T) {
const ref = "#/paths/~1wrongcode/get/responses/two-hundred"
require.Errorf(t, rewriteParentRef(sp, ref, spec.Ref{}), wantedFailure)
})

t.Run("with panic case", func(t *testing.T) {
t.Run("should not call with types other than *Schema or *Swagger", func(t *testing.T) {
require.Panics(t, func() {
_, _, _ = getPointerFromKey("oops", "#/key")
})

require.Panics(t, func() {
_, _, _, _ = getParentFromKey("oops", "#/key")
})

require.Panics(t, func() {
_ = UpdateRef("oops", "#/key", spec.Ref{})
})
})
})
}

0 comments on commit c406152

Please sign in to comment.