github.com/josephspurrier/go-swagger@v0.2.1-0.20221129144919-1f672a142a00/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  	var 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  	var 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  
   243  func verifyNumeric2Words(t *testing.T, matcher *regexp.Regexp, name1, name2 string) {
   244  	extraSpaces := []string{"", " ", "  ", "     "}
   245  	prefixes := []string{"//", "*", ""}
   246  	validNumericArgs := []string{"0", "1234", "-1235", "0.0", "1234.0394", "-2948.484"}
   247  	invalidNumericArgs := []string{"1A3F", "2e10", "*12", "12*"}
   248  
   249  	var cnt int
   250  	for _, pref := range prefixes {
   251  		for _, es1 := range extraSpaces {
   252  			for _, es2 := range extraSpaces {
   253  				for _, es3 := range extraSpaces {
   254  					for _, es4 := range extraSpaces {
   255  						for _, vv := range validNumericArgs {
   256  							lines := []string{
   257  								strings.Join([]string{pref, es1, name1, es2, name2, es3, ":", es4, vv}, ""),
   258  								strings.Join([]string{pref, es1, strings.Title(name1), es2, strings.Title(name2), es3, ":", es4, vv}, ""), //nolint:staticcheck
   259  								strings.Join([]string{pref, es1, strings.Title(name1), es2, name2, es3, ":", es4, vv}, ""),                //nolint:staticcheck
   260  								strings.Join([]string{pref, es1, name1, es2, strings.Title(name2), es3, ":", es4, vv}, ""),                //nolint:staticcheck
   261  							}
   262  							for _, line := range lines {
   263  								matches := matcher.FindStringSubmatch(line)
   264  								assert.Len(t, matches, 2)
   265  								assert.Equal(t, vv, matches[1])
   266  								cnt++
   267  							}
   268  						}
   269  						for _, iv := range invalidNumericArgs {
   270  							lines := []string{
   271  								strings.Join([]string{pref, es1, name1, es2, name2, es3, ":", es4, iv}, ""),
   272  								strings.Join([]string{pref, es1, strings.Title(name1), es2, strings.Title(name2), es3, ":", es4, iv}, ""), //nolint:staticcheck
   273  								strings.Join([]string{pref, es1, strings.Title(name1), es2, name2, es3, ":", es4, iv}, ""),                //nolint:staticcheck
   274  								strings.Join([]string{pref, es1, name1, es2, strings.Title(name2), es3, ":", es4, iv}, ""),                //nolint:staticcheck
   275  							}
   276  							for _, line := range lines {
   277  								matches := matcher.FindStringSubmatch(line)
   278  								assert.Empty(t, matches)
   279  								cnt++
   280  							}
   281  						}
   282  					}
   283  				}
   284  			}
   285  		}
   286  	}
   287  	var Debug = os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   288  	if Debug {
   289  		fmt.Printf("tested %d %s %s combinations\n", cnt, name1, name2)
   290  	}
   291  }
   292  
   293  func verifyMinMax(t *testing.T, matcher *regexp.Regexp, name string, operators []string) {
   294  	extraSpaces := []string{"", " ", "  ", "     "}
   295  	prefixes := []string{"//", "*", ""}
   296  	validNumericArgs := []string{"0", "1234", "-1235", "0.0", "1234.0394", "-2948.484"}
   297  	invalidNumericArgs := []string{"1A3F", "2e10", "*12", "12*"}
   298  
   299  	var cnt int
   300  	for _, pref := range prefixes {
   301  		for _, es1 := range extraSpaces {
   302  			for _, wrd := range makeMinMax(name) {
   303  				for _, es2 := range extraSpaces {
   304  					for _, es3 := range extraSpaces {
   305  						for _, op := range operators {
   306  							for _, es4 := range extraSpaces {
   307  								for _, vv := range validNumericArgs {
   308  									line := strings.Join([]string{pref, es1, wrd, es2, ":", es3, op, es4, vv}, "")
   309  									matches := matcher.FindStringSubmatch(line)
   310  									// fmt.Printf("matching %q with %q, matches (%d): %v\n", line, matcher, len(matches), matches)
   311  									assert.Len(t, matches, 3)
   312  									assert.Equal(t, vv, matches[2])
   313  									cnt++
   314  								}
   315  								for _, iv := range invalidNumericArgs {
   316  									line := strings.Join([]string{pref, es1, wrd, es2, ":", es3, op, es4, iv}, "")
   317  									matches := matcher.FindStringSubmatch(line)
   318  									assert.Empty(t, matches)
   319  									cnt++
   320  								}
   321  							}
   322  						}
   323  					}
   324  				}
   325  			}
   326  		}
   327  	}
   328  	var Debug = os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != ""
   329  	if Debug {
   330  		fmt.Printf("tested %d %s combinations\n", cnt, name)
   331  	}
   332  }
   333  
   334  func verifySwaggerOneArgSwaggerTag(t *testing.T, matcher *regexp.Regexp, prefixes, validParams, invalidParams []string) {
   335  	for _, pref := range prefixes {
   336  		for _, param := range validParams {
   337  			line := pref + param
   338  			matches := matcher.FindStringSubmatch(line)
   339  			if assert.Len(t, matches, 2) {
   340  				assert.Equal(t, strings.TrimSpace(param), matches[1])
   341  			}
   342  		}
   343  	}
   344  
   345  	for _, pref := range prefixes {
   346  		for _, param := range invalidParams {
   347  			line := pref + param
   348  			matches := matcher.FindStringSubmatch(line)
   349  			assert.Empty(t, matches)
   350  		}
   351  	}
   352  }
   353  
   354  func verifySwaggerMultiArgSwaggerTag(t *testing.T, matcher *regexp.Regexp, prefixes, validParams, invalidParams []string) {
   355  	var actualParams []string
   356  	for i := 0; i < len(validParams); i++ {
   357  		var vp []string
   358  		for j := 0; j < (i + 1); j++ {
   359  			vp = append(vp, validParams[j])
   360  		}
   361  		actualParams = append(actualParams, strings.Join(vp, " "))
   362  	}
   363  	for _, pref := range prefixes {
   364  		for _, param := range actualParams {
   365  			line := pref + param
   366  			matches := matcher.FindStringSubmatch(line)
   367  			// fmt.Printf("matching %q with %q, matches (%d): %v\n", line, matcher, len(matches), matches)
   368  			assert.Len(t, matches, 2)
   369  			assert.Equal(t, strings.TrimSpace(param), matches[1])
   370  		}
   371  	}
   372  
   373  	for _, pref := range prefixes {
   374  		for _, param := range invalidParams {
   375  			line := pref + param
   376  			matches := matcher.FindStringSubmatch(line)
   377  			assert.Empty(t, matches)
   378  		}
   379  	}
   380  }