...

Source file src/github.com/go-openapi/swag/util_test.go

Documentation: github.com/go-openapi/swag

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package swag
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  	"testing"
    21  	"time"
    22  	"unicode"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  type translationSample struct {
    29  	str, out string
    30  }
    31  
    32  func titleize(s string) string { return strings.ToTitle(s[:1]) + lower(s[1:]) }
    33  
    34  func init() {
    35  	AddInitialisms("elb", "cap", "capwd", "wd")
    36  }
    37  
    38  func TestIndexOfInitialismsSorted(t *testing.T) {
    39  	configuredInitialisms := map[string]bool{
    40  		"ACL":   true,
    41  		"API":   true,
    42  		"ASCII": true,
    43  		"CPU":   true,
    44  		"CSS":   true,
    45  		"DNS":   true,
    46  		"VM":    true,
    47  		"XML":   true,
    48  		"XMPP":  true,
    49  		"XSRF":  true,
    50  		"XSS":   true,
    51  	}
    52  
    53  	goldenSample := []string{
    54  		"ASCII",
    55  		"XMPP",
    56  		"XSRF",
    57  		"ACL",
    58  		"API",
    59  		"CPU",
    60  		"CSS",
    61  		"DNS",
    62  		"XML",
    63  		"XSS",
    64  		"VM",
    65  	}
    66  	for i := 0; i < 50; i++ {
    67  		sample := newIndexOfInitialisms().load(configuredInitialisms).sorted()
    68  		failMsg := "equal sorted initialisms should be always equal"
    69  
    70  		if !assert.Equal(t, goldenSample, sample, failMsg) {
    71  			t.FailNow()
    72  		}
    73  	}
    74  }
    75  
    76  func TestHighUnicode(t *testing.T) {
    77  	ss := "日本語sample 2 Text"
    78  	rss := []rune(ss)
    79  
    80  	require.False(t, rss[0] < unicode.MaxASCII && unicode.IsLetter(rss[0]))
    81  }
    82  
    83  const (
    84  	textTitle  = "Text"
    85  	blankText  = " text"
    86  	dashText   = "-text"
    87  	uscoreText = "_text"
    88  
    89  	sampleTitle  = "Sample"
    90  	sampleString = "sample"
    91  	sampleBlank  = "sample "
    92  	sampleDash   = "sample-"
    93  	sampleUscore = "sample_"
    94  )
    95  
    96  func TestToGoName(t *testing.T) {
    97  	samples := []translationSample{
    98  		{"@Type", "AtType"},
    99  		{"Sample@where", "SampleAtWhere"},
   100  		{"Id", "ID"},
   101  		{"SomethingTTLSeconds", "SomethingTTLSeconds"},
   102  		{"sample text", "SampleText"},
   103  		{"IPv6Address", "IPV6Address"},
   104  		{"IPv4Address", "IPV4Address"},
   105  		{"sample-text", "SampleText"},
   106  		{"sample_text", "SampleText"},
   107  		{"sampleText", "SampleText"},
   108  		{"sample 2 Text", "Sample2Text"},
   109  		{"findThingById", "FindThingByID"},
   110  		{"日本語sample 2 Text", "X日本語sample2Text"},
   111  		{"日本語findThingById", "X日本語findThingByID"},
   112  		{"findTHINGSbyID", "FindTHINGSbyID"},
   113  		{"x-isAnOptionalHeader0", "XIsAnOptionalHeader0"},
   114  		{"get$ref", "GetDollarRef"},
   115  		{"éget$ref", "ÉgetDollarRef"},
   116  		{"日get$ref", "X日getDollarRef"},
   117  		{"", ""},
   118  		{"?", ""},
   119  		{"!", "Bang"},
   120  		{"", ""},
   121  	}
   122  
   123  	for _, k := range commonInitialisms.sorted() {
   124  		k = upper(k)
   125  
   126  		samples = append(samples,
   127  			translationSample{sampleBlank + lower(k) + blankText, sampleTitle + k + textTitle},
   128  			translationSample{sampleDash + lower(k) + dashText, sampleTitle + k + textTitle},
   129  			translationSample{sampleUscore + lower(k) + uscoreText, sampleTitle + k + textTitle},
   130  			translationSample{sampleString + titleize(k) + textTitle, sampleTitle + k + textTitle},
   131  			translationSample{sampleBlank + lower(k), sampleTitle + k},
   132  			translationSample{sampleDash + lower(k), sampleTitle + k},
   133  			translationSample{sampleUscore + lower(k), sampleTitle + k},
   134  			translationSample{sampleString + titleize(k), sampleTitle + k},
   135  			translationSample{sampleBlank + titleize(k) + blankText, sampleTitle + k + textTitle},
   136  			translationSample{sampleDash + titleize(k) + dashText, sampleTitle + k + textTitle},
   137  			translationSample{sampleUscore + titleize(k) + uscoreText, sampleTitle + k + textTitle},
   138  		)
   139  	}
   140  
   141  	for _, sample := range samples {
   142  		result := ToGoName(sample.str)
   143  		assert.Equal(t, sample.out, result,
   144  			"ToGoName(%q) == %q but got %q", sample.str, sample.out, result)
   145  	}
   146  }
   147  
   148  func TestContainsStringsCI(t *testing.T) {
   149  	list := []string{"hello", "world", "and", "such"}
   150  
   151  	assert.True(t, ContainsStringsCI(list, "hELLo"))
   152  	assert.True(t, ContainsStringsCI(list, "world"))
   153  	assert.True(t, ContainsStringsCI(list, "AND"))
   154  	assert.False(t, ContainsStringsCI(list, "nuts"))
   155  }
   156  
   157  func TestContainsStrings(t *testing.T) {
   158  	list := []string{"hello", "world", "and", "such"}
   159  
   160  	assert.True(t, ContainsStrings(list, "hello"))
   161  	assert.False(t, ContainsStrings(list, "hELLo"))
   162  	assert.True(t, ContainsStrings(list, "world"))
   163  	assert.False(t, ContainsStrings(list, "World"))
   164  	assert.True(t, ContainsStrings(list, "and"))
   165  	assert.False(t, ContainsStrings(list, "AND"))
   166  	assert.False(t, ContainsStrings(list, "nuts"))
   167  }
   168  
   169  const (
   170  	collectionFormatComma = "csv"
   171  )
   172  
   173  func TestSplitByFormat(t *testing.T) {
   174  	expected := []string{"one", "two", "three"}
   175  	for _, fmt := range []string{collectionFormatComma, collectionFormatPipe, collectionFormatTab, collectionFormatSpace, collectionFormatMulti} {
   176  
   177  		var actual []string
   178  		switch fmt {
   179  		case collectionFormatMulti:
   180  			assert.Nil(t, SplitByFormat("", fmt))
   181  			assert.Nil(t, SplitByFormat("blah", fmt))
   182  		case collectionFormatSpace:
   183  			actual = SplitByFormat(strings.Join(expected, " "), fmt)
   184  			assert.EqualValues(t, expected, actual)
   185  		case collectionFormatPipe:
   186  			actual = SplitByFormat(strings.Join(expected, "|"), fmt)
   187  			assert.EqualValues(t, expected, actual)
   188  		case collectionFormatTab:
   189  			actual = SplitByFormat(strings.Join(expected, "\t"), fmt)
   190  			assert.EqualValues(t, expected, actual)
   191  		default:
   192  			actual = SplitByFormat(strings.Join(expected, ","), fmt)
   193  			assert.EqualValues(t, expected, actual)
   194  		}
   195  	}
   196  }
   197  
   198  func TestJoinByFormat(t *testing.T) {
   199  	for _, fmt := range []string{collectionFormatComma, collectionFormatPipe, collectionFormatTab, collectionFormatSpace, collectionFormatMulti} {
   200  
   201  		lval := []string{"one", "two", "three"}
   202  		var expected []string
   203  		switch fmt {
   204  		case collectionFormatMulti:
   205  			expected = lval
   206  		case collectionFormatSpace:
   207  			expected = []string{strings.Join(lval, " ")}
   208  		case collectionFormatPipe:
   209  			expected = []string{strings.Join(lval, "|")}
   210  		case collectionFormatTab:
   211  			expected = []string{strings.Join(lval, "\t")}
   212  		default:
   213  			expected = []string{strings.Join(lval, ",")}
   214  		}
   215  		assert.Nil(t, JoinByFormat(nil, fmt))
   216  		assert.EqualValues(t, expected, JoinByFormat(lval, fmt))
   217  	}
   218  }
   219  
   220  func TestToFileName(t *testing.T) {
   221  	samples := []translationSample{
   222  		{"SampleText", "sample_text"},
   223  		{"FindThingByID", "find_thing_by_id"},
   224  		{"CAPWD.folwdBylc", "capwd_folwd_bylc"},
   225  		{"CAPWDfolwdBylc", "cap_w_dfolwd_bylc"},
   226  		{"CAP_WD_folwdBylc", "cap_wd_folwd_bylc"},
   227  		{"TypeOAI_alias", "type_oai_alias"},
   228  		{"Type_OAI_alias", "type_oai_alias"},
   229  		{"Type_OAIAlias", "type_oai_alias"},
   230  		{"ELB.HTTPLoadBalancer", "elb_http_load_balancer"},
   231  		{"elbHTTPLoadBalancer", "elb_http_load_balancer"},
   232  		{"ELBHTTPLoadBalancer", "elb_http_load_balancer"},
   233  		{"get$Ref", "get_dollar_ref"},
   234  	}
   235  	for _, k := range commonInitialisms.sorted() {
   236  		samples = append(samples,
   237  			translationSample{sampleTitle + k + textTitle, sampleUscore + lower(k) + uscoreText},
   238  		)
   239  	}
   240  
   241  	for _, sample := range samples {
   242  		result := ToFileName(sample.str)
   243  		assert.Equal(t, sample.out, ToFileName(sample.str),
   244  			"ToFileName(%q) == %q but got %q", sample.str, sample.out, result)
   245  	}
   246  }
   247  
   248  func TestToCommandName(t *testing.T) {
   249  	samples := []translationSample{
   250  		{"SampleText", "sample-text"},
   251  		{"FindThingByID", "find-thing-by-id"},
   252  		{"elbHTTPLoadBalancer", "elb-http-load-balancer"},
   253  		{"get$ref", "get-dollar-ref"},
   254  		{"get!ref", "get-bang-ref"},
   255  	}
   256  
   257  	for _, k := range commonInitialisms.sorted() {
   258  		samples = append(samples,
   259  			translationSample{sampleTitle + k + textTitle, sampleDash + lower(k) + dashText},
   260  		)
   261  	}
   262  
   263  	for _, sample := range samples {
   264  		assert.Equal(t, sample.out, ToCommandName(sample.str))
   265  	}
   266  }
   267  
   268  func TestToHumanName(t *testing.T) {
   269  	samples := []translationSample{
   270  		{"Id", "Id"},
   271  		{"SampleText", "sample text"},
   272  		{"FindThingByID", "find thing by ID"},
   273  		{"elbHTTPLoadBalancer", "elb HTTP load balancer"},
   274  	}
   275  
   276  	for _, k := range commonInitialisms.sorted() {
   277  		samples = append(samples,
   278  			translationSample{sampleTitle + k + textTitle, sampleBlank + k + blankText},
   279  		)
   280  	}
   281  
   282  	for _, sample := range samples {
   283  		assert.Equal(t, sample.out, ToHumanNameLower(sample.str))
   284  	}
   285  }
   286  
   287  func TestToJSONName(t *testing.T) {
   288  	samples := []translationSample{
   289  		{"SampleText", "sampleText"},
   290  		{"FindThingByID", "findThingById"},
   291  		{"elbHTTPLoadBalancer", "elbHttpLoadBalancer"},
   292  		{"get$ref", "getDollarRef"},
   293  		{"get!ref", "getBangRef"},
   294  	}
   295  
   296  	for _, k := range commonInitialisms.sorted() {
   297  		samples = append(samples,
   298  			translationSample{sampleTitle + k + textTitle, sampleString + titleize(k) + textTitle},
   299  		)
   300  	}
   301  
   302  	for _, sample := range samples {
   303  		assert.Equal(t, sample.out, ToJSONName(sample.str))
   304  	}
   305  }
   306  
   307  type SimpleZeroes struct {
   308  	ID   string
   309  	Name string
   310  }
   311  type ZeroesWithTime struct {
   312  	Time time.Time
   313  }
   314  
   315  type dummyZeroable struct {
   316  	zero bool
   317  }
   318  
   319  func (d dummyZeroable) IsZero() bool {
   320  	return d.zero
   321  }
   322  
   323  func TestIsZero(t *testing.T) {
   324  	var strs [5]string
   325  	var strss []string
   326  	var a int
   327  	var b int8
   328  	var c int16
   329  	var d int32
   330  	var e int64
   331  	var f uint
   332  	var g uint8
   333  	var h uint16
   334  	var i uint32
   335  	var j uint64
   336  	var k map[string]string
   337  	var l interface{}
   338  	var m *SimpleZeroes
   339  	var n string
   340  	var o SimpleZeroes
   341  	var p ZeroesWithTime
   342  	var q time.Time
   343  	data := []struct {
   344  		Data     interface{}
   345  		Expected bool
   346  	}{
   347  		{a, true},
   348  		{b, true},
   349  		{c, true},
   350  		{d, true},
   351  		{e, true},
   352  		{f, true},
   353  		{g, true},
   354  		{h, true},
   355  		{i, true},
   356  		{j, true},
   357  		{k, true},
   358  		{l, true},
   359  		{m, true},
   360  		{n, true},
   361  		{o, true},
   362  		{p, true},
   363  		{q, true},
   364  		{strss, true},
   365  		{strs, true},
   366  		{"", true},
   367  		{nil, true},
   368  		{1, false},
   369  		{0, true},
   370  		{int8(1), false},
   371  		{int8(0), true},
   372  		{int16(1), false},
   373  		{int16(0), true},
   374  		{int32(1), false},
   375  		{int32(0), true},
   376  		{int64(1), false},
   377  		{int64(0), true},
   378  		{uint(1), false},
   379  		{uint(0), true},
   380  		{uint8(1), false},
   381  		{uint8(0), true},
   382  		{uint16(1), false},
   383  		{uint16(0), true},
   384  		{uint32(1), false},
   385  		{uint32(0), true},
   386  		{uint64(1), false},
   387  		{uint64(0), true},
   388  		{0.0, true},
   389  		{0.1, false},
   390  		{float32(0.0), true},
   391  		{float32(0.1), false},
   392  		{float64(0.0), true},
   393  		{float64(0.1), false},
   394  		{[...]string{}, true},
   395  		{[...]string{"hello"}, false},
   396  		{[]string(nil), true},
   397  		{[]string{"a"}, false},
   398  		{&dummyZeroable{true}, true},
   399  		{&dummyZeroable{false}, false},
   400  		{(*dummyZeroable)(nil), true},
   401  	}
   402  
   403  	for _, it := range data {
   404  		assert.Equal(t, it.Expected, IsZero(it.Data), fmt.Sprintf("%#v", it.Data))
   405  	}
   406  }
   407  
   408  func TestCamelize(t *testing.T) {
   409  	samples := []translationSample{
   410  		{"SampleText", "Sampletext"},
   411  		{"FindThingByID", "Findthingbyid"},
   412  		{"CAPWD.folwdBylc", "Capwd.folwdbylc"},
   413  		{"CAPWDfolwdBylc", "Capwdfolwdbylc"},
   414  		{"CAP_WD_folwdBylc", "Cap_wd_folwdbylc"},
   415  		{"TypeOAI_alias", "Typeoai_alias"},
   416  		{"Type_OAI_alias", "Type_oai_alias"},
   417  		{"Type_OAIAlias", "Type_oaialias"},
   418  		{"ELB.HTTPLoadBalancer", "Elb.httploadbalancer"},
   419  		{"elbHTTPLoadBalancer", "Elbhttploadbalancer"},
   420  		{"ELBHTTPLoadBalancer", "Elbhttploadbalancer"},
   421  		{"12ab", "12ab"},
   422  		{"get$Ref", "Get$ref"},
   423  		{"get!Ref", "Get!ref"},
   424  	}
   425  
   426  	for _, sample := range samples {
   427  		res := Camelize(sample.str)
   428  		assert.Equalf(t, sample.out, res, "expected Camelize(%q)=%q, got %q", sample.str, sample.out, res)
   429  	}
   430  }
   431  
   432  func TestToHumanNameTitle(t *testing.T) {
   433  	samples := []translationSample{
   434  		{"SampleText", "Sample Text"},
   435  		{"FindThingByID", "Find Thing By ID"},
   436  		{"CAPWD.folwdBylc", "CAPWD Folwd Bylc"},
   437  		{"CAPWDfolwdBylc", "CAP W Dfolwd Bylc"},
   438  		{"CAP_WD_folwdBylc", "CAP WD Folwd Bylc"},
   439  		{"TypeOAI_alias", "Type OAI Alias"},
   440  		{"Type_OAI_alias", "Type OAI Alias"},
   441  		{"Type_OAIAlias", "Type OAI Alias"},
   442  		{"ELB.HTTPLoadBalancer", "ELB HTTP Load Balancer"},
   443  		{"elbHTTPLoadBalancer", "elb HTTP Load Balancer"},
   444  		{"ELBHTTPLoadBalancer", "ELB HTTP Load Balancer"},
   445  		{"get$ref", "Get Dollar Ref"},
   446  		{"get!ref", "Get Bang Ref"},
   447  	}
   448  
   449  	for _, sample := range samples {
   450  		res := ToHumanNameTitle(sample.str)
   451  		assert.Equalf(t, sample.out, res, "expected ToHumanNameTitle(%q)=%q, got %q", sample.str, sample.out, res)
   452  	}
   453  }
   454  
   455  func TestToVarName(t *testing.T) {
   456  	samples := []translationSample{
   457  		{"SampleText", "sampleText"},
   458  		{"FindThingByID", "findThingByID"},
   459  		{"CAPWD.folwdBylc", "cAPWDFolwdBylc"},
   460  		{"CAPWDfolwdBylc", "cAPWDfolwdBylc"},
   461  		{"CAP_WD_folwdBylc", "cAPWDFolwdBylc"},
   462  		{"TypeOAI_alias", "typeOAIAlias"},
   463  		{"Type_OAI_alias", "typeOAIAlias"},
   464  		{"Type_OAIAlias", "typeOAIAlias"},
   465  		{"ELB.HTTPLoadBalancer", "eLBHTTPLoadBalancer"},
   466  		{"elbHTTPLoadBalancer", "eLBHTTPLoadBalancer"},
   467  		{"ELBHTTPLoadBalancer", "eLBHTTPLoadBalancer"},
   468  		{"Id", "id"},
   469  		{"HTTP", "http"},
   470  		{"A", "a"},
   471  		{"get$ref", "getDollarRef"},
   472  		{"get!ref", "getBangRef"},
   473  	}
   474  
   475  	for _, sample := range samples {
   476  		res := ToVarName(sample.str)
   477  		assert.Equalf(t, sample.out, res, "expected ToVarName(%q)=%q, got %q", sample.str, sample.out, res)
   478  	}
   479  }
   480  
   481  func TestToGoNameUnicode(t *testing.T) {
   482  	defer func() { GoNamePrefixFunc = nil }()
   483  	GoNamePrefixFunc = func(name string) string {
   484  		// this is the pascalize func from go-swagger codegen
   485  		arg := []rune(name)
   486  		if len(arg) == 0 || arg[0] > '9' {
   487  			return ""
   488  		}
   489  		if arg[0] == '+' {
   490  			return "Plus"
   491  		}
   492  		if arg[0] == '-' {
   493  			return "Minus"
   494  		}
   495  
   496  		return "Nr"
   497  	}
   498  
   499  	samples := []translationSample{
   500  		{"123_a", "Nr123a"},
   501  		{"!123_a", "Bang123a"},
   502  		{"+123_a", "Plus123a"},
   503  		{"abc", "Abc"},
   504  		{"éabc", "Éabc"},
   505  		{":éabc", "Éabc"},
   506  		{"get$ref", "GetDollarRef"},
   507  		{"get!ref", "GetBangRef"},
   508  		{"get&ref", "GetAndRef"},
   509  		{"get|ref", "GetPipeRef"},
   510  		// TODO: non unicode char
   511  	}
   512  
   513  	for _, sample := range samples {
   514  		assert.Equal(t, sample.out, ToGoName(sample.str))
   515  	}
   516  }
   517  

View as plain text