...

Source file src/github.com/go-openapi/spec/helpers_spec_test.go

Documentation: github.com/go-openapi/spec

     1  package spec_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/go-openapi/spec"
    11  	"github.com/go-openapi/swag"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  var (
    17  	rex        = regexp.MustCompile(`"\$ref":\s*"(.*?)"`)
    18  	testLoader func(string) (json.RawMessage, error)
    19  )
    20  
    21  func init() {
    22  	// mimics what the go-openapi/load does
    23  	testLoader = func(path string) (json.RawMessage, error) {
    24  		if swag.YAMLMatcher(path) {
    25  			return swag.YAMLDoc(path)
    26  		}
    27  		data, err := swag.LoadFromFileOrHTTP(path)
    28  		if err != nil {
    29  			return nil, err
    30  		}
    31  		return json.RawMessage(data), nil
    32  	}
    33  }
    34  
    35  func loadOrFail(t *testing.T, path string) *spec.Swagger {
    36  	raw, err := testLoader(path)
    37  	require.NoErrorf(t, err, "can't load fixture %s: %v", path, err)
    38  	swspec := new(spec.Swagger)
    39  	err = json.Unmarshal(raw, swspec)
    40  	require.NoError(t, err)
    41  	return swspec
    42  }
    43  
    44  func assertRefInJSON(t testing.TB, jazon, prefix string) {
    45  	// assert a match in a references
    46  	m := rex.FindAllStringSubmatch(jazon, -1)
    47  	require.NotNil(t, m)
    48  
    49  	for _, matched := range m {
    50  		subMatch := matched[1]
    51  		assert.True(t, strings.HasPrefix(subMatch, prefix),
    52  			"expected $ref to match %q, got: %s", prefix, matched[0])
    53  	}
    54  }
    55  
    56  func assertRefInJSONRegexp(t testing.TB, jazon, match string) {
    57  	// assert a match in a references
    58  	m := rex.FindAllStringSubmatch(jazon, -1)
    59  	require.NotNil(t, m)
    60  
    61  	refMatch, err := regexp.Compile(match)
    62  	require.NoError(t, err)
    63  
    64  	for _, matched := range m {
    65  		subMatch := matched[1]
    66  		assert.True(t, refMatch.MatchString(subMatch),
    67  			"expected $ref to match %q, got: %s", match, matched[0])
    68  	}
    69  }
    70  
    71  // assertRefExpand ensures that all $ref in some json doc expand properly against a root document.
    72  //
    73  // "exclude" is a regexp pattern to ignore certain $ref (e.g. some specs may embed $ref that are not processed, such as extensions).
    74  func assertRefExpand(t *testing.T, jazon, _ string, root interface{}, opts ...*spec.ExpandOptions) {
    75  	if len(opts) > 0 {
    76  		assertRefWithFunc(t, "expand-with-base", jazon, "", func(t *testing.T, match string) {
    77  			ref := spec.RefSchema(match)
    78  			options := *opts[0]
    79  			require.NoError(t, spec.ExpandSchemaWithBasePath(ref, nil, &options))
    80  		})
    81  		return
    82  	}
    83  
    84  	assertRefWithFunc(t, "expand", jazon, "", func(t *testing.T, match string) {
    85  		ref := spec.RefSchema(match)
    86  		require.NoError(t, spec.ExpandSchema(ref, root, nil))
    87  	})
    88  }
    89  
    90  func assertRefResolve(t *testing.T, jazon, exclude string, root interface{}, opts ...*spec.ExpandOptions) {
    91  	assertRefWithFunc(t, "resolve", jazon, exclude, func(t *testing.T, match string) {
    92  		ref := spec.MustCreateRef(match)
    93  		var (
    94  			sch *spec.Schema
    95  			err error
    96  		)
    97  		if len(opts) > 0 {
    98  			options := *opts[0]
    99  			sch, err = spec.ResolveRefWithBase(root, &ref, &options)
   100  		} else {
   101  			sch, err = spec.ResolveRef(root, &ref)
   102  		}
   103  
   104  		require.NoErrorf(t, err, `%v: for "$ref": %q`, err, match)
   105  		require.NotNil(t, sch)
   106  	})
   107  }
   108  
   109  // assertRefWithFunc ensures that all $ref in a j
   110  //
   111  // "exclude" is a regexp pattern to ignore certain $ref (e.g. some specs may embed $ref that are not processed, such as extensions).
   112  func assertRefWithFunc(t *testing.T, name, jazon, exclude string, asserter func(*testing.T, string)) {
   113  	filterRex := regexp.MustCompile(exclude)
   114  	m := rex.FindAllStringSubmatch(jazon, -1)
   115  	require.NotNil(t, m)
   116  
   117  	allRefs := make(map[string]struct{}, len(m))
   118  	for _, toPin := range m {
   119  		matched := toPin
   120  		subMatch := matched[1]
   121  		if exclude != "" && filterRex.MatchString(subMatch) {
   122  			continue
   123  		}
   124  
   125  		_, ok := allRefs[subMatch]
   126  		if ok {
   127  			continue
   128  		}
   129  
   130  		allRefs[subMatch] = struct{}{}
   131  
   132  		t.Run(fmt.Sprintf("%s-%s-%s", t.Name(), name, subMatch), func(t *testing.T) {
   133  			// t.Parallel()
   134  			asserter(t, subMatch)
   135  		})
   136  	}
   137  }
   138  
   139  func asJSON(t testing.TB, sp interface{}) string {
   140  	bbb, err := json.MarshalIndent(sp, "", " ")
   141  	require.NoError(t, err)
   142  
   143  	return string(bbb)
   144  }
   145  
   146  // assertNoRef ensures that no $ref is remaining in json doc
   147  func assertNoRef(t testing.TB, jazon string) {
   148  	m := rex.FindAllStringSubmatch(jazon, -1)
   149  	require.Nil(t, m)
   150  }
   151  

View as plain text