github.com/go-swagger/go-swagger@v0.31.0/codescan/regexprs_test.go (about)

     1  package codescan
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestSchemaValueExtractors(t *testing.T) {
    14  	strfmts := []string{
    15  		"// swagger:strfmt ",
    16  		"* swagger:strfmt ",
    17  		"* swagger:strfmt ",
    18  		" swagger:strfmt ",
    19  		"swagger:strfmt ",
    20  		"// swagger:strfmt    ",
    21  		"* swagger:strfmt     ",
    22  		"* swagger:strfmt    ",
    23  		" swagger:strfmt     ",
    24  		"swagger:strfmt      ",
    25  	}
    26  	models := []string{
    27  		"// swagger:model ",
    28  		"* swagger:model ",
    29  		"* swagger:model ",
    30  		" swagger:model ",
    31  		"swagger:model ",
    32  		"// swagger:model    ",
    33  		"* swagger:model     ",
    34  		"* swagger:model    ",
    35  		" swagger:model     ",
    36  		"swagger:model      ",
    37  	}
    38  
    39  	allOf := []string{
    40  		"// swagger:allOf ",
    41  		"* swagger:allOf ",
    42  		"* swagger:allOf ",
    43  		" swagger:allOf ",
    44  		"swagger:allOf ",
    45  		"// swagger:allOf    ",
    46  		"* swagger:allOf     ",
    47  		"* swagger:allOf    ",
    48  		" swagger:allOf     ",
    49  		"swagger:allOf      ",
    50  	}
    51  
    52  	parameters := []string{
    53  		"// swagger:parameters ",
    54  		"* swagger:parameters ",
    55  		"* swagger:parameters ",
    56  		" swagger:parameters ",
    57  		"swagger:parameters ",
    58  		"// swagger:parameters    ",
    59  		"* swagger:parameters     ",
    60  		"* swagger:parameters    ",
    61  		" swagger:parameters     ",
    62  		"swagger:parameters      ",
    63  	}
    64  
    65  	validParams := []string{
    66  		"yada123",
    67  		"date",
    68  		"date-time",
    69  		"long-combo-1-with-combo-2-and-a-3rd-one-too",
    70  	}
    71  	invalidParams := []string{
    72  		"1-yada-3",
    73  		"1-2-3",
    74  		"-yada-3",
    75  		"-2-3",
    76  		"*blah",
    77  		"blah*",
    78  	}
    79  
    80  	verifySwaggerOneArgSwaggerTag(t, rxStrFmt, strfmts, validParams, append(invalidParams, "", "  ", " "))
    81  	verifySwaggerOneArgSwaggerTag(t, rxModelOverride, models, append(validParams, "", "  ", " "), invalidParams)
    82  
    83  	verifySwaggerOneArgSwaggerTag(t, rxAllOf, allOf, append(validParams, "", "  ", " "), invalidParams)
    84  
    85  	verifySwaggerMultiArgSwaggerTag(t, rxParametersOverride, parameters, validParams, invalidParams)
    86  
    87  	verifyMinMax(t, rxf(rxMinimumFmt, ""), "min", []string{"", ">", "="})
    88  	verifyMinMax(t, rxf(rxMinimumFmt, fmt.Sprintf(rxItemsPrefixFmt, 1)), "items.min", []string{"", ">", "="})
    89  	verifyMinMax(t, rxf(rxMaximumFmt, ""), "max", []string{"", "<", "="})
    90  	verifyMinMax(t, rxf(rxMaximumFmt, fmt.Sprintf(rxItemsPrefixFmt, 1)), "items.max", []string{"", "<", "="})
    91  	verifyNumeric2Words(t, rxf(rxMultipleOfFmt, ""), "multiple", "of")
    92  	verifyNumeric2Words(t, rxf(rxMultipleOfFmt, fmt.Sprintf(rxItemsPrefixFmt, 1)), "items.multiple", "of")
    93  
    94  	verifyIntegerMinMaxManyWords(t, rxf(rxMinLengthFmt, ""), "min", []string{"len", "length"})
    95  	// pattern
    96  	extraSpaces := []string{"", " ", "  ", "     "}
    97  	prefixes := []string{"//", "*", ""}
    98  	patArgs := []string{"^\\w+$", "[A-Za-z0-9-.]*"}
    99  	patNames := []string{"pattern", "Pattern"}
   100  	for _, pref := range prefixes {
   101  		for _, es1 := range extraSpaces {
   102  			for _, nm := range patNames {
   103  				for _, es2 := range extraSpaces {
   104  					for _, es3 := range extraSpaces {
   105  						for _, arg := range patArgs {
   106  							line := strings.Join([]string{pref, es1, nm, es2, ":", es3, arg}, "")
   107  							matches := rxf(rxPatternFmt, "").FindStringSubmatch(line)
   108  							assert.Len(t, matches, 2)
   109  							assert.Equal(t, arg, matches[1])
   110  						}
   111  					}
   112  				}
   113  			}
   114  		}
   115  	}
   116  
   117  	verifyIntegerMinMaxManyWords(t, rxf(rxMinItemsFmt, ""), "min", []string{"items"})
   118  	verifyBoolean(t, rxf(rxUniqueFmt, ""), []string{"unique"}, nil)
   119  
   120  	verifyBoolean(t, rxReadOnly, []string{"read"}, []string{"only"})
   121  	verifyBoolean(t, rxRequired, []string{"required"}, nil)
   122  }
   123  
   124  func makeMinMax(lower string) (res []string) {
   125  	for _, a := range []string{"", "imum"} {
   126  		res = append(res, lower+a, strings.Title(lower)+a) //nolint:staticcheck
   127  	}
   128  	return
   129  }
   130  
   131  func verifyBoolean(t *testing.T, matcher *regexp.Regexp, names, names2 []string) {
   132  	extraSpaces := []string{"", " ", "  ", "     "}
   133  	prefixes := []string{"//", "*", ""}
   134  	validArgs := []string{"true", "false"}
   135  	invalidArgs := []string{"TRUE", "FALSE", "t", "f", "1", "0", "True", "False", "true*", "false*"}
   136  	var nms []string
   137  	for _, nm := range names {
   138  		nms = append(nms, nm, strings.Title(nm)) //nolint:staticcheck
   139  	}
   140  
   141  	var nms2 []string
   142  	for _, nm := range names2 {
   143  		nms2 = append(nms2, nm, strings.Title(nm)) //nolint:staticcheck
   144  	}
   145  
   146  	var rnms []string
   147  	if len(nms2) > 0 {
   148  		for _, nm := range nms {
   149  			for _, es := range append(extraSpaces, "-") {
   150  				for _, nm2 := range nms2 {
   151  					rnms = append(rnms, strings.Join([]string{nm, es, nm2}, ""))
   152  				}
   153  			}
   154  		}
   155  	} else {
   156  		rnms = nms
   157  	}
   158  
   159  	var cnt int
   160  	for _, pref := range prefixes {
   161  		for _, es1 := range extraSpaces {
   162  			for _, nm := range rnms {
   163  				for _, es2 := range extraSpaces {
   164  					for _, es3 := range extraSpaces {
   165  						for _, vv := range validArgs {
   166  							line := strings.Join([]string{pref, es1, nm, es2, ":", es3, vv}, "")
   167  							matches := matcher.FindStringSubmatch(line)
   168  							assert.Len(t, matches, 2)
   169  							assert.Equal(t, vv, matches[1])
   170  							cnt++
   171  						}
   172  						for _, iv := range invalidArgs {
   173  							line := strings.Join([]string{pref, es1, nm, es2, ":", es3, iv}, "")
   174  							matches := matcher.FindStringSubmatch(line)
   175  							assert.Empty(t, matches)
   176  							cnt++
   177  						}
   178  					}
   179  				}
   180  			}
   181  		}
   182  	}
   183  	var nm2 string
   184  	if len(names2) > 0 {
   185  		nm2 = " " + names2[0]
   186  	}
   187  	Debug := os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   188  	if Debug {
   189  		fmt.Printf("tested %d %s%s combinations\n", cnt, names[0], nm2)
   190  	}
   191  }
   192  
   193  func verifyIntegerMinMaxManyWords(t *testing.T, matcher *regexp.Regexp, name1 string, words []string) {
   194  	extraSpaces := []string{"", " ", "  ", "     "}
   195  	prefixes := []string{"//", "*", ""}
   196  	validNumericArgs := []string{"0", "1234"}
   197  	invalidNumericArgs := []string{"1A3F", "2e10", "*12", "12*", "-1235", "0.0", "1234.0394", "-2948.484"}
   198  
   199  	var names []string
   200  	for _, w := range words {
   201  		names = append(names, w, strings.Title(w)) //nolint:staticcheck
   202  	}
   203  
   204  	var cnt int
   205  	for _, pref := range prefixes {
   206  		for _, es1 := range extraSpaces {
   207  			for _, nm1 := range makeMinMax(name1) {
   208  				for _, es2 := range append(extraSpaces, "-") {
   209  					for _, nm2 := range names {
   210  						for _, es3 := range extraSpaces {
   211  							for _, es4 := range extraSpaces {
   212  								for _, vv := range validNumericArgs {
   213  									line := strings.Join([]string{pref, es1, nm1, es2, nm2, es3, ":", es4, vv}, "")
   214  									matches := matcher.FindStringSubmatch(line)
   215  									assert.Len(t, matches, 2)
   216  									assert.Equal(t, vv, matches[1])
   217  									cnt++
   218  								}
   219  								for _, iv := range invalidNumericArgs {
   220  									line := strings.Join([]string{pref, es1, nm1, es2, nm2, es3, ":", es4, iv}, "")
   221  									matches := matcher.FindStringSubmatch(line)
   222  									assert.Empty(t, matches)
   223  									cnt++
   224  								}
   225  							}
   226  						}
   227  					}
   228  				}
   229  			}
   230  		}
   231  	}
   232  	var nm2 string
   233  	if len(words) > 0 {
   234  		nm2 = " " + words[0]
   235  	}
   236  	Debug := os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   237  	if Debug {
   238  		fmt.Printf("tested %d %s%s combinations\n", cnt, name1, nm2)
   239  	}
   240  }
   241  
   242  func verifyNumeric2Words(t *testing.T, matcher *regexp.Regexp, name1, name2 string) {
   243  	extraSpaces := []string{"", " ", "  ", "     "}
   244  	prefixes := []string{"//", "*", ""}
   245  	validNumericArgs := []string{"0", "1234", "-1235", "0.0", "1234.0394", "-2948.484"}
   246  	invalidNumericArgs := []string{"1A3F", "2e10", "*12", "12*"}
   247  
   248  	var cnt int
   249  	for _, pref := range prefixes {
   250  		for _, es1 := range extraSpaces {
   251  			for _, es2 := range extraSpaces {
   252  				for _, es3 := range extraSpaces {
   253  					for _, es4 := range extraSpaces {
   254  						for _, vv := range validNumericArgs {
   255  							lines := []string{
   256  								strings.Join([]string{pref, es1, name1, es2, name2, es3, ":", es4, vv}, ""),
   257  								strings.Join([]string{pref, es1, strings.Title(name1), es2, strings.Title(name2), es3, ":", es4, vv}, ""), //nolint:staticcheck
   258  								strings.Join([]string{pref, es1, strings.Title(name1), es2, name2, es3, ":", es4, vv}, ""),                //nolint:staticcheck
   259  								strings.Join([]string{pref, es1, name1, es2, strings.Title(name2), es3, ":", es4, vv}, ""),                //nolint:staticcheck
   260  							}
   261  							for _, line := range lines {
   262  								matches := matcher.FindStringSubmatch(line)
   263  								assert.Len(t, matches, 2)
   264  								assert.Equal(t, vv, matches[1])
   265  								cnt++
   266  							}
   267  						}
   268  						for _, iv := range invalidNumericArgs {
   269  							lines := []string{
   270  								strings.Join([]string{pref, es1, name1, es2, name2, es3, ":", es4, iv}, ""),
   271  								strings.Join([]string{pref, es1, strings.Title(name1), es2, strings.Title(name2), es3, ":", es4, iv}, ""), //nolint:staticcheck
   272  								strings.Join([]string{pref, es1, strings.Title(name1), es2, name2, es3, ":", es4, iv}, ""),                //nolint:staticcheck
   273  								strings.Join([]string{pref, es1, name1, es2, strings.Title(name2), es3, ":", es4, iv}, ""),                //nolint:staticcheck
   274  							}
   275  							for _, line := range lines {
   276  								matches := matcher.FindStringSubmatch(line)
   277  								assert.Empty(t, matches)
   278  								cnt++
   279  							}
   280  						}
   281  					}
   282  				}
   283  			}
   284  		}
   285  	}
   286  	Debug := os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   287  	if Debug {
   288  		fmt.Printf("tested %d %s %s combinations\n", cnt, name1, name2)
   289  	}
   290  }
   291  
   292  func verifyMinMax(t *testing.T, matcher *regexp.Regexp, name string, operators []string) {
   293  	extraSpaces := []string{"", " ", "  ", "     "}
   294  	prefixes := []string{"//", "*", ""}
   295  	validNumericArgs := []string{"0", "1234", "-1235", "0.0", "1234.0394", "-2948.484"}
   296  	invalidNumericArgs := []string{"1A3F", "2e10", "*12", "12*"}
   297  
   298  	var cnt int
   299  	for _, pref := range prefixes {
   300  		for _, es1 := range extraSpaces {
   301  			for _, wrd := range makeMinMax(name) {
   302  				for _, es2 := range extraSpaces {
   303  					for _, es3 := range extraSpaces {
   304  						for _, op := range operators {
   305  							for _, es4 := range extraSpaces {
   306  								for _, vv := range validNumericArgs {
   307  									line := strings.Join([]string{pref, es1, wrd, es2, ":", es3, op, es4, vv}, "")
   308  									matches := matcher.FindStringSubmatch(line)
   309  									// fmt.Printf("matching %q with %q, matches (%d): %v\n", line, matcher, len(matches), matches)
   310  									assert.Len(t, matches, 3)
   311  									assert.Equal(t, vv, matches[2])
   312  									cnt++
   313  								}
   314  								for _, iv := range invalidNumericArgs {
   315  									line := strings.Join([]string{pref, es1, wrd, es2, ":", es3, op, es4, iv}, "")
   316  									matches := matcher.FindStringSubmatch(line)
   317  									assert.Empty(t, matches)
   318  									cnt++
   319  								}
   320  							}
   321  						}
   322  					}
   323  				}
   324  			}
   325  		}
   326  	}
   327  	Debug := os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   328  	if Debug {
   329  		fmt.Printf("tested %d %s combinations\n", cnt, name)
   330  	}
   331  }
   332  
   333  func verifySwaggerOneArgSwaggerTag(t *testing.T, matcher *regexp.Regexp, prefixes, validParams, invalidParams []string) {
   334  	for _, pref := range prefixes {
   335  		for _, param := range validParams {
   336  			line := pref + param
   337  			matches := matcher.FindStringSubmatch(line)
   338  			if assert.Len(t, matches, 2) {
   339  				assert.Equal(t, strings.TrimSpace(param), matches[1])
   340  			}
   341  		}
   342  	}
   343  
   344  	for _, pref := range prefixes {
   345  		for _, param := range invalidParams {
   346  			line := pref + param
   347  			matches := matcher.FindStringSubmatch(line)
   348  			assert.Empty(t, matches)
   349  		}
   350  	}
   351  }
   352  
   353  func verifySwaggerMultiArgSwaggerTag(t *testing.T, matcher *regexp.Regexp, prefixes, validParams, invalidParams []string) {
   354  	var actualParams []string
   355  	for i := 0; i < len(validParams); i++ {
   356  		var vp []string
   357  		for j := 0; j < (i + 1); j++ {
   358  			vp = append(vp, validParams[j])
   359  		}
   360  		actualParams = append(actualParams, strings.Join(vp, " "))
   361  	}
   362  	for _, pref := range prefixes {
   363  		for _, param := range actualParams {
   364  			line := pref + param
   365  			matches := matcher.FindStringSubmatch(line)
   366  			// fmt.Printf("matching %q with %q, matches (%d): %v\n", line, matcher, len(matches), matches)
   367  			assert.Len(t, matches, 2)
   368  			assert.Equal(t, strings.TrimSpace(param), matches[1])
   369  		}
   370  	}
   371  
   372  	for _, pref := range prefixes {
   373  		for _, param := range invalidParams {
   374  			line := pref + param
   375  			matches := matcher.FindStringSubmatch(line)
   376  			assert.Empty(t, matches)
   377  		}
   378  	}
   379  }