1package analysis_test
2
3import (
4	"encoding/json"
5	"fmt"
6	"regexp"
7	"testing"
8
9	"github.com/go-openapi/spec"
10	"github.com/stretchr/testify/assert"
11	"github.com/stretchr/testify/require"
12)
13
14var (
15	rex = regexp.MustCompile(`"\$ref":\s*"(.*?)"`)
16)
17
18func assertRefResolve(t *testing.T, jazon, exclude string, root interface{}, opts ...*spec.ExpandOptions) {
19	assertRefWithFunc(t, "resolve", jazon, exclude, func(t *testing.T, match string) {
20		ref := spec.MustCreateRef(match)
21		var (
22			sch *spec.Schema
23			err error
24		)
25		if len(opts) > 0 {
26			options := *opts[0]
27			sch, err = spec.ResolveRefWithBase(root, &ref, &options)
28		} else {
29			sch, err = spec.ResolveRef(root, &ref)
30		}
31
32		require.NoErrorf(t, err, `%v: for "$ref": %q`, err, match)
33		require.NotNil(t, sch)
34	})
35}
36
37// assertNoRef ensures that no $ref is remaining in json doc
38func assertNoRef(t testing.TB, jazon string) {
39	m := rex.FindAllStringSubmatch(jazon, -1)
40	require.Nil(t, m)
41}
42
43func assertRefInJSONRegexp(t testing.TB, jazon, match string) {
44	// assert a match in a references
45	m := rex.FindAllStringSubmatch(jazon, -1)
46	require.NotNil(t, m)
47
48	refMatch, err := regexp.Compile(match)
49	require.NoError(t, err)
50
51	for _, matched := range m {
52		subMatch := matched[1]
53		assert.True(t, refMatch.MatchString(subMatch),
54			"expected $ref to match %q, got: %s", match, matched[0])
55	}
56}
57
58// assertRefResolve ensures that all $ref in some json doc verify some asserting func.
59//
60// "exclude" is a regexp pattern to ignore certain $ref (e.g. some specs may embed $ref that are not processed, such as extensions).
61func assertRefWithFunc(t *testing.T, name, jazon, exclude string, asserter func(*testing.T, string)) {
62	filterRex := regexp.MustCompile(exclude)
63	m := rex.FindAllStringSubmatch(jazon, -1)
64	require.NotNil(t, m)
65
66	allRefs := make(map[string]struct{}, len(m))
67	for _, toPin := range m {
68		matched := toPin
69		subMatch := matched[1]
70		if exclude != "" && filterRex.MatchString(subMatch) {
71			continue
72		}
73
74		_, ok := allRefs[subMatch]
75		if ok {
76			continue
77		}
78
79		allRefs[subMatch] = struct{}{}
80
81		t.Run(fmt.Sprintf("%s-%s-%s", t.Name(), name, subMatch), func(t *testing.T) {
82			t.Parallel()
83			asserter(t, subMatch)
84		})
85	}
86}
87
88func asJSON(t testing.TB, sp interface{}) string {
89	bbb, err := json.MarshalIndent(sp, "", " ")
90	require.NoError(t, err)
91
92	return string(bbb)
93}
94