github.com/josephspurrier/go-swagger@v0.2.1-0.20221129144919-1f672a142a00/generator/template_repo_test.go (about)

     1  package generator
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"log"
     7  	"os"
     8  	"testing"
     9  
    10  	"github.com/go-openapi/loads"
    11  	"github.com/go-openapi/swag"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  const (
    17  	// Test template environment
    18  	singleTemplate        = `test`
    19  	multipleDefinitions   = `{{ define "T1" }}T1{{end}}{{ define "T2" }}T2{{end}}`
    20  	dependantTemplate     = `{{ template "T1" }}D1`
    21  	cirularDeps1          = `{{ define "T1" }}{{ .Name }}: {{ range .Children }}{{ template "T2" . }}{{end}}{{end}}{{template "T1" . }}`
    22  	cirularDeps2          = `{{ define "T2" }}{{if .Recurse }}{{ template "T1" . }}{{ else }}Children{{end}}{{end}}`
    23  	customHeader          = `custom header`
    24  	customMultiple        = `{{define "bindprimitiveparam" }}custom primitive{{end}}`
    25  	customNewTemplate     = `new template`
    26  	customExistingUsesNew = `{{define "bindprimitiveparam" }}{{ template "newtemplate" }}{{end}}`
    27  )
    28  
    29  func testFuncTpl() string {
    30  	return `
    31  Pascalize={{ pascalize "WeArePonies_Of_the_round table" }}
    32  Snakize={{ snakize "WeArePonies_Of_the_round table" }}
    33  Humanize={{ humanize "WeArePonies_Of_the_round table" }}
    34  PluralizeFirstWord={{ pluralizeFirstWord "pony of the round table" }}
    35  PluralizeFirstOfOneWord={{ pluralizeFirstWord "dwarf" }}
    36  PluralizeFirstOfNoWord={{ pluralizeFirstWord "" }}
    37  DropPackage={{ dropPackage "prefix.suffix" }}
    38  DropNoPackage={{ dropPackage "suffix" }}
    39  DropEmptyPackage={{ dropPackage "" }}
    40  ContainsString={{ contains .DependsOn "x"}}
    41  DoesNotContainString={{ contains .DependsOn "y"}}
    42  PadSurround1={{ padSurround "padme" "-" 3 12}}
    43  PadSurround2={{ padSurround "padme" "-" 0 12}}
    44  Json={{ json .DefaultImports }}
    45  PrettyJson={{ prettyjson . }}
    46  Snakize1={{ snakize "endingInOsNameLinux" }}
    47  Snakize2={{ snakize "endingInArchNameLinuxAmd64" }}
    48  Snakize3={{ snakize "endingInTest" }}
    49  toPackage1={{ toPackage "a/b-c/d-e" }}
    50  toPackage2={{ toPackage "a.a/b_c/d_e" }}
    51  toPackage3={{ toPackage "d_e" }}
    52  toPackage4={{ toPackage "d-e" }}
    53  toPackageName={{ toPackageName "d-e/f-g" }}
    54  PascalizeSpecialChar1={{ pascalize "+1" }}
    55  PascalizeSpecialChar2={{ pascalize "-1" }}
    56  PascalizeSpecialChar3={{ pascalize "1" }}
    57  PascalizeSpecialChar4={{ pascalize "-" }}
    58  PascalizeSpecialChar5={{ pascalize "+" }}
    59  PascalizeCleanupEnumVariant1={{ pascalize (cleanupEnumVariant "2.4Ghz") }}
    60  Dict={{ template "dictTemplate" dict "Animal" "Pony" "Shape" "round" "Furniture" "table" }}
    61  {{ define "dictTemplate" }}{{ .Animal }} of the {{ .Shape }} {{ .Furniture }}{{ end }}
    62  `
    63  }
    64  
    65  func TestTemplates_CustomTemplates(t *testing.T) {
    66  
    67  	var buf bytes.Buffer
    68  	headerTempl, err := templates.Get("bindprimitiveparam")
    69  	assert.NoError(t, err)
    70  
    71  	err = headerTempl.Execute(&buf, nil)
    72  	require.NoError(t, err)
    73  	require.NotNil(t, buf)
    74  	assert.Equal(t, "\n", buf.String())
    75  
    76  	buf.Reset()
    77  	err = templates.AddFile("bindprimitiveparam", customHeader)
    78  	assert.NoError(t, err)
    79  
    80  	headerTempl, err = templates.Get("bindprimitiveparam")
    81  	assert.NoError(t, err)
    82  	assert.NotNil(t, headerTempl)
    83  
    84  	err = headerTempl.Execute(&buf, nil)
    85  	assert.NoError(t, err)
    86  	assert.Equal(t, "custom header", buf.String())
    87  
    88  }
    89  
    90  func TestTemplates_CustomTemplatesMultiple(t *testing.T) {
    91  	var buf bytes.Buffer
    92  
    93  	err := templates.AddFile("differentFileName", customMultiple)
    94  	assert.NoError(t, err)
    95  
    96  	headerTempl, err := templates.Get("bindprimitiveparam")
    97  	assert.NoError(t, err)
    98  
    99  	err = headerTempl.Execute(&buf, nil)
   100  	require.NoError(t, err)
   101  
   102  	assert.Equal(t, "custom primitive", buf.String())
   103  }
   104  
   105  func TestTemplates_CustomNewTemplates(t *testing.T) {
   106  	var buf bytes.Buffer
   107  
   108  	err := templates.AddFile("newtemplate", customNewTemplate)
   109  	assert.NoError(t, err)
   110  
   111  	err = templates.AddFile("existingUsesNew", customExistingUsesNew)
   112  	assert.NoError(t, err)
   113  
   114  	headerTempl, err := templates.Get("bindprimitiveparam")
   115  	assert.NoError(t, err)
   116  
   117  	err = headerTempl.Execute(&buf, nil)
   118  	require.NoError(t, err)
   119  
   120  	assert.Equal(t, "new template", buf.String())
   121  }
   122  
   123  func TestTemplates_RepoLoadingTemplates(t *testing.T) {
   124  
   125  	repo := NewRepository(nil)
   126  
   127  	err := repo.AddFile("simple", singleTemplate)
   128  	assert.NoError(t, err)
   129  
   130  	templ, err := repo.Get("simple")
   131  	require.NoError(t, err)
   132  
   133  	var b bytes.Buffer
   134  	err = templ.Execute(&b, nil)
   135  	require.NoError(t, err)
   136  
   137  	assert.Equal(t, "test", b.String())
   138  }
   139  
   140  func TestTemplates_RepoLoadsAllTemplatesDefined(t *testing.T) {
   141  
   142  	var b bytes.Buffer
   143  	repo := NewRepository(nil)
   144  
   145  	err := repo.AddFile("multiple", multipleDefinitions)
   146  	assert.NoError(t, err)
   147  
   148  	templ, err := repo.Get("multiple")
   149  	assert.NoError(t, err)
   150  
   151  	err = templ.Execute(&b, nil)
   152  	require.NoError(t, err)
   153  
   154  	assert.Equal(t, "", b.String())
   155  
   156  	templ, err = repo.Get("T1")
   157  	require.NoError(t, err)
   158  	require.NotNil(t, templ)
   159  
   160  	err = templ.Execute(&b, nil)
   161  	require.NoError(t, err)
   162  
   163  	assert.Equal(t, "T1", b.String())
   164  }
   165  
   166  type testData struct {
   167  	Children []testData
   168  	Name     string
   169  	Recurse  bool
   170  }
   171  
   172  func TestTemplates_RepoLoadsAllDependantTemplates(t *testing.T) {
   173  
   174  	var b bytes.Buffer
   175  	repo := NewRepository(nil)
   176  
   177  	err := repo.AddFile("multiple", multipleDefinitions)
   178  	assert.NoError(t, err)
   179  
   180  	err = repo.AddFile("dependant", dependantTemplate)
   181  	assert.NoError(t, err)
   182  
   183  	templ, err := repo.Get("dependant")
   184  	require.NoError(t, err)
   185  	require.NotNil(t, templ)
   186  
   187  	err = templ.Execute(&b, nil)
   188  	require.NoError(t, err)
   189  
   190  	assert.Equal(t, "T1D1", b.String())
   191  }
   192  
   193  func TestTemplates_RepoRecursiveTemplates(t *testing.T) {
   194  
   195  	var b bytes.Buffer
   196  	repo := NewRepository(nil)
   197  
   198  	err := repo.AddFile("c1", cirularDeps1)
   199  	assert.NoError(t, err)
   200  
   201  	err = repo.AddFile("c2", cirularDeps2)
   202  	assert.NoError(t, err)
   203  
   204  	templ, err := repo.Get("c1")
   205  	require.NoError(t, err)
   206  	require.NotNil(t, templ)
   207  
   208  	data := testData{
   209  		Name: "Root",
   210  		Children: []testData{
   211  			{Recurse: false},
   212  		},
   213  	}
   214  	expected := `Root: Children`
   215  	err = templ.Execute(&b, data)
   216  	require.NoError(t, err)
   217  	assert.Equal(t, expected, b.String())
   218  
   219  	data = testData{
   220  		Name: "Root",
   221  		Children: []testData{
   222  			{Name: "Child1", Recurse: true, Children: []testData{{Name: "Child2"}}},
   223  		},
   224  	}
   225  
   226  	b.Reset()
   227  
   228  	expected = `Root: Child1: Children`
   229  
   230  	err = templ.Execute(&b, data)
   231  	require.NoError(t, err)
   232  
   233  	assert.Equal(t, expected, b.String())
   234  
   235  	data = testData{
   236  		Name: "Root",
   237  		Children: []testData{
   238  			{Name: "Child1", Recurse: false, Children: []testData{{Name: "Child2"}}},
   239  		},
   240  	}
   241  
   242  	b.Reset()
   243  
   244  	expected = `Root: Children`
   245  
   246  	err = templ.Execute(&b, data)
   247  	require.NoError(t, err)
   248  
   249  	assert.Equal(t, expected, b.String())
   250  }
   251  
   252  // Test that definitions are available to templates
   253  // TODO: should test also with the codeGenApp context
   254  
   255  // Test copyright definition
   256  func TestTemplates_DefinitionCopyright(t *testing.T) {
   257  	const copyright = `{{ .Copyright }}`
   258  	log.SetOutput(os.Stdout)
   259  
   260  	repo := NewRepository(nil)
   261  
   262  	err := repo.AddFile("copyright", copyright)
   263  	assert.NoError(t, err)
   264  
   265  	templ, err := repo.Get("copyright")
   266  	require.NoError(t, err)
   267  	require.NotNil(t, templ)
   268  
   269  	opts := opts()
   270  	opts.Copyright = "My copyright clause"
   271  	expected := opts.Copyright
   272  
   273  	// executes template against model definitions
   274  	genModel, err := getModelEnvironment("../fixtures/codegen/todolist.models.yml", opts)
   275  	require.NoError(t, err)
   276  	require.NotNil(t, genModel)
   277  
   278  	rendered := bytes.NewBuffer(nil)
   279  	err = templ.Execute(rendered, genModel)
   280  	assert.NoError(t, err)
   281  	assert.Equal(t, expected, rendered.String())
   282  
   283  	// executes template against operations definitions
   284  	genOperation, err := getOperationEnvironment("get", "/media/search", "../fixtures/codegen/instagram.yml", opts)
   285  	require.NoError(t, err)
   286  	require.NotNil(t, genOperation)
   287  
   288  	rendered.Reset()
   289  
   290  	err = templ.Execute(rendered, genOperation)
   291  	require.NoError(t, err)
   292  
   293  	assert.Equal(t, expected, rendered.String())
   294  
   295  }
   296  
   297  // Test TargetImportPath definition
   298  func TestTemplates_DefinitionTargetImportPath(t *testing.T) {
   299  	const targetImportPath = `{{ .TargetImportPath }}`
   300  	log.SetOutput(os.Stdout)
   301  
   302  	repo := NewRepository(nil)
   303  
   304  	err := repo.AddFile("targetimportpath", targetImportPath)
   305  	assert.NoError(t, err)
   306  
   307  	templ, err := repo.Get("targetimportpath")
   308  	require.NoError(t, err)
   309  	require.NotNil(t, templ)
   310  
   311  	opts := opts()
   312  	// Non existing target would panic: to be tested too, but in another module
   313  	opts.Target = "../fixtures"
   314  	var expected = "github.com/go-swagger/go-swagger/fixtures"
   315  
   316  	// executes template against model definitions
   317  	genModel, err := getModelEnvironment("../fixtures/codegen/todolist.models.yml", opts)
   318  	require.NoError(t, err)
   319  	require.NotNil(t, genModel)
   320  
   321  	rendered := bytes.NewBuffer(nil)
   322  	err = templ.Execute(rendered, genModel)
   323  	assert.NoError(t, err)
   324  
   325  	assert.Equal(t, expected, rendered.String())
   326  
   327  	// executes template against operations definitions
   328  	genOperation, err := getOperationEnvironment("get", "/media/search", "../fixtures/codegen/instagram.yml", opts)
   329  	require.NoError(t, err)
   330  	require.NotNil(t, genOperation)
   331  
   332  	rendered.Reset()
   333  
   334  	err = templ.Execute(rendered, genOperation)
   335  	require.NoError(t, err)
   336  
   337  	assert.Equal(t, expected, rendered.String())
   338  
   339  }
   340  
   341  // Simulates a definition environment for model templates
   342  func getModelEnvironment(spec string, opts *GenOpts) (*GenDefinition, error) {
   343  	// Don't want stderr output to pollute CI
   344  	log.SetOutput(io.Discard)
   345  	defer log.SetOutput(os.Stdout)
   346  
   347  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   348  	if err != nil {
   349  		return nil, err
   350  	}
   351  	definitions := specDoc.Spec().Definitions
   352  
   353  	for k, schema := range definitions {
   354  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   355  		if err != nil {
   356  			return nil, err
   357  		}
   358  		// One is enough
   359  		return genModel, nil
   360  	}
   361  	return nil, nil
   362  }
   363  
   364  // Simulates a definition environment for operation templates
   365  func getOperationEnvironment(operation string, path string, spec string, opts *GenOpts) (*GenOperation, error) {
   366  	// Don't want stderr output to pollute CI
   367  	log.SetOutput(io.Discard)
   368  	defer log.SetOutput(os.Stdout)
   369  
   370  	b, err := methodPathOpBuilder(operation, path, spec)
   371  	if err != nil {
   372  		return nil, err
   373  	}
   374  	b.GenOpts = opts
   375  	g, err := b.MakeOperation()
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  	return &g, nil
   380  }
   381  
   382  // Exercises FuncMap
   383  // Just running basic tests to make sure the function map works and all functions are available as expected.
   384  // More complete unit tests are provided by go-openapi/swag.
   385  func TestTemplates_FuncMap(t *testing.T) {
   386  	log.SetOutput(os.Stdout)
   387  	funcTpl := testFuncTpl()
   388  
   389  	err := templates.AddFile("functpl", funcTpl)
   390  	require.NoError(t, err)
   391  
   392  	templ, err := templates.Get("functpl")
   393  	require.NoError(t, err)
   394  
   395  	opts := opts()
   396  	// executes template against model definitions
   397  	genModel, err := getModelEnvironment("../fixtures/codegen/todolist.models.yml", opts)
   398  	require.NoError(t, err)
   399  
   400  	genModel.DependsOn = []string{"x", "z"}
   401  	rendered := bytes.NewBuffer(nil)
   402  	err = templ.Execute(rendered, genModel)
   403  	require.NoError(t, err)
   404  
   405  	assert.Contains(t, rendered.String(), "Pascalize=WeArePoniesOfTheRoundTable\n")
   406  	assert.Contains(t, rendered.String(), "Snakize=we_are_ponies_of_the_round_table\n")
   407  	assert.Contains(t, rendered.String(), "Humanize=we are ponies of the round table\n")
   408  	assert.Contains(t, rendered.String(), "PluralizeFirstWord=ponies of the round table\n")
   409  	assert.Contains(t, rendered.String(), "PluralizeFirstOfOneWord=dwarves\n")
   410  	assert.Contains(t, rendered.String(), "PluralizeFirstOfNoWord=\n")
   411  	assert.Contains(t, rendered.String(), "DropPackage=suffix\n")
   412  	assert.Contains(t, rendered.String(), "DropNoPackage=suffix\n")
   413  	assert.Contains(t, rendered.String(), "DropEmptyPackage=\n")
   414  	assert.Contains(t, rendered.String(), "DropEmptyPackage=\n")
   415  	assert.Contains(t, rendered.String(), "ContainsString=true\n")
   416  	assert.Contains(t, rendered.String(), "DoesNotContainString=false\n")
   417  	assert.Contains(t, rendered.String(), "PadSurround1=-,-,-,padme,-,-,-,-,-,-,-,-\n")
   418  	assert.Contains(t, rendered.String(), "PadSurround2=padme,-,-,-,-,-,-,-,-,-,-,-\n")
   419  	assert.Contains(t, rendered.String(), `Json={"errors":"github.com/go-openapi/errors","runtime":"github.com/go-openapi/runtime","swag":"github.com/go-openapi/swag","validate":"github.com/go-openapi/validate"}`)
   420  	assert.Contains(t, rendered.String(), "\"TargetImportPath\": \"github.com/go-swagger/go-swagger/generator\"")
   421  	assert.Contains(t, rendered.String(), "Snakize1=ending_in_os_name_linux_swagger\n")
   422  	assert.Contains(t, rendered.String(), "Snakize2=ending_in_arch_name_linux_amd64_swagger\n")
   423  	assert.Contains(t, rendered.String(), "Snakize3=ending_in_test_swagger\n")
   424  	assert.Contains(t, rendered.String(), "toPackage1=a/b-c/d_e\n")
   425  	assert.Contains(t, rendered.String(), "toPackage2=a.a/b_c/d_e\n")
   426  	assert.Contains(t, rendered.String(), "toPackage3=d_e\n")
   427  	assert.Contains(t, rendered.String(), "toPackage4=d_e\n")
   428  	assert.Contains(t, rendered.String(), "toPackageName=f_g\n")
   429  	assert.Contains(t, rendered.String(), "PascalizeSpecialChar1=Plus1\n")
   430  	assert.Contains(t, rendered.String(), "PascalizeSpecialChar2=Minus1\n")
   431  	assert.Contains(t, rendered.String(), "PascalizeSpecialChar3=Nr1\n")
   432  	assert.Contains(t, rendered.String(), "PascalizeSpecialChar4=Minus\n")
   433  	assert.Contains(t, rendered.String(), "PascalizeSpecialChar5=Plus\n")
   434  	assert.Contains(t, rendered.String(), "PascalizeCleanupEnumVariant1=Nr2Dot4Ghz")
   435  	assert.Contains(t, rendered.String(), "Dict=Pony of the round table\n")
   436  }
   437  
   438  // AddFile() global package function (protected vs unprotected)
   439  // Mostly unused in tests, since the Repository.AddFile()
   440  // is generally preferred.
   441  func TestTemplates_AddFile(t *testing.T) {
   442  	log.SetOutput(os.Stdout)
   443  	funcTpl := testFuncTpl()
   444  
   445  	// unprotected
   446  	err := AddFile("functpl", funcTpl)
   447  	require.NoError(t, err)
   448  
   449  	_, err = templates.Get("functpl")
   450  	require.NoError(t, err)
   451  
   452  	// protected
   453  	err = AddFile("schemabody", funcTpl)
   454  	require.Error(t, err)
   455  	assert.Contains(t, err.Error(), "cannot overwrite protected template")
   456  }
   457  
   458  // Test LoadDir
   459  func TestTemplates_LoadDir(t *testing.T) {
   460  	log.SetOutput(os.Stdout)
   461  
   462  	// Fails
   463  	err := templates.LoadDir("")
   464  	require.Error(t, err)
   465  	assert.Contains(t, err.Error(), "could not complete")
   466  
   467  	// Fails again (from any dir?)
   468  	err = templates.LoadDir("templates")
   469  	require.Error(t, err)
   470  	assert.Contains(t, err.Error(), "cannot overwrite protected template")
   471  
   472  	// TODO: success case
   473  	// To force a success, we need to empty the global list of protected
   474  	// templates...
   475  	origProtectedTemplates := protectedTemplates
   476  
   477  	defer func() {
   478  		// Restore variable initialized with package
   479  		protectedTemplates = origProtectedTemplates
   480  	}()
   481  
   482  	protectedTemplates = make(map[string]bool)
   483  	repo := NewRepository(FuncMapFunc(DefaultLanguageFunc()))
   484  	err = repo.LoadDir("templates")
   485  	assert.NoError(t, err)
   486  }
   487  
   488  // Test LoadDir
   489  func TestTemplates_SetAllowOverride(t *testing.T) {
   490  	log.SetOutput(os.Stdout)
   491  
   492  	// adding protected file with allowOverride set to false fails
   493  	templates.SetAllowOverride(false)
   494  	err := templates.AddFile("schemabody", "some data")
   495  	require.Error(t, err)
   496  	assert.Contains(t, err.Error(), "cannot overwrite protected template schemabody")
   497  
   498  	// adding protected file with allowOverride set to true should not fail
   499  	templates.SetAllowOverride(true)
   500  	err = templates.AddFile("schemabody", "some data")
   501  	assert.NoError(t, err)
   502  }
   503  
   504  // Test LoadContrib
   505  func TestTemplates_LoadContrib(t *testing.T) {
   506  	tests := []struct {
   507  		name      string
   508  		template  string
   509  		wantError bool
   510  	}{
   511  		{
   512  			name:      "None_existing_contributor_template",
   513  			template:  "NonExistingContributorTemplate",
   514  			wantError: true,
   515  		},
   516  		{
   517  			name:      "Existing_contributor",
   518  			template:  "stratoscale",
   519  			wantError: false,
   520  		},
   521  	}
   522  
   523  	for _, tt := range tests {
   524  		t.Run(tt.name, func(t *testing.T) {
   525  			err := templates.LoadContrib(tt.template)
   526  			if tt.wantError {
   527  				assert.Error(t, err)
   528  			} else {
   529  				assert.NoError(t, err)
   530  			}
   531  		})
   532  	}
   533  }
   534  
   535  // TODO: test error case in LoadDefaults()
   536  // test DumpTemplates()
   537  func TestTemplates_DumpTemplates(t *testing.T) {
   538  	buf := bytes.NewBuffer(nil)
   539  	log.SetOutput(buf)
   540  	defer func() {
   541  		log.SetOutput(os.Stdout)
   542  	}()
   543  
   544  	templates.DumpTemplates()
   545  	assert.NotEmpty(t, buf)
   546  	// Sample output
   547  	assert.Contains(t, buf.String(), "## tupleSerializer")
   548  	assert.Contains(t, buf.String(), "Defined in `tupleserializer.gotmpl`")
   549  	assert.Contains(t, buf.String(), "####requires \n - schemaType")
   550  }
   551  
   552  func TestFuncMap_Pascalize(t *testing.T) {
   553  	assert.Equal(t, "Plus1", pascalize("+1"))
   554  	assert.Equal(t, "Plus", pascalize("+"))
   555  	assert.Equal(t, "Minus1", pascalize("-1"))
   556  	assert.Equal(t, "Minus", pascalize("-"))
   557  	assert.Equal(t, "Nr8", pascalize("8"))
   558  	assert.Equal(t, "Asterisk", pascalize("*"))
   559  	assert.Equal(t, "ForwardSlash", pascalize("/"))
   560  	assert.Equal(t, "EqualSign", pascalize("="))
   561  
   562  	assert.Equal(t, "Hello", pascalize("+hello"))
   563  
   564  	// other values from swag rules
   565  	assert.Equal(t, "At8", pascalize("@8"))
   566  	assert.Equal(t, "AtHello", pascalize("@hello"))
   567  	assert.Equal(t, "Bang8", pascalize("!8"))
   568  	assert.Equal(t, "At", pascalize("@"))
   569  
   570  	// # values
   571  	assert.Equal(t, "Hello", pascalize("#hello"))
   572  	assert.Equal(t, "BangHello", pascalize("#!hello"))
   573  	assert.Equal(t, "HashTag8", pascalize("#8"))
   574  	assert.Equal(t, "HashTag", pascalize("#"))
   575  
   576  	// single '_'
   577  	assert.Equal(t, "Nr", pascalize("_"))
   578  	assert.Equal(t, "Hello", pascalize("_hello"))
   579  
   580  	// remove spaces
   581  	assert.Equal(t, "HelloWorld", pascalize("# hello world"))
   582  	assert.Equal(t, "HashTag8HelloWorld", pascalize("# 8 hello world"))
   583  
   584  	assert.Equal(t, "Empty", pascalize(""))
   585  }
   586  
   587  func TestFuncMap_DropPackage(t *testing.T) {
   588  	assert.Equal(t, "trail", dropPackage("base.trail"))
   589  	assert.Equal(t, "trail", dropPackage("base.another.trail"))
   590  	assert.Equal(t, "trail", dropPackage("trail"))
   591  }
   592  
   593  func TestFuncMap_AsJSON(t *testing.T) {
   594  	for _, jsonFunc := range []func(interface{}) (string, error){
   595  		asJSON,
   596  		asPrettyJSON,
   597  	} {
   598  		res, err := jsonFunc(struct {
   599  			A string `json:"a"`
   600  			B int
   601  		}{A: "good", B: 3})
   602  		require.NoError(t, err)
   603  		assert.JSONEq(t, `{"a":"good","B":3}`, res)
   604  
   605  		_, err = jsonFunc(struct {
   606  			A string `json:"a"`
   607  			B func() string
   608  		}{A: "good", B: func() string { return "" }})
   609  		require.Error(t, err)
   610  	}
   611  }
   612  
   613  func TestFuncMap_Dict(t *testing.T) {
   614  	d, err := dict("a", "b", "c", "d")
   615  	require.NoError(t, err)
   616  	assert.Equal(t, map[string]interface{}{"a": "b", "c": "d"}, d)
   617  
   618  	// odd number of arguments
   619  	_, err = dict("a", "b", "c")
   620  	require.Error(t, err)
   621  
   622  	// none-string key
   623  	_, err = dict("a", "b", 3, "d")
   624  	require.Error(t, err)
   625  }
   626  
   627  func TestIsInteger(t *testing.T) {
   628  	var (
   629  		nilString *string
   630  		nilInt    *int
   631  		nilFloat  *float32
   632  	)
   633  
   634  	for _, anInteger := range []interface{}{
   635  		int8(4),
   636  		int16(4),
   637  		int32(4),
   638  		int64(4),
   639  		int(4),
   640  		swag.Int(4),
   641  		swag.Int32(4),
   642  		swag.Int64(4),
   643  		swag.Uint(4),
   644  		swag.Uint32(4),
   645  		swag.Uint64(4),
   646  		float32(12),
   647  		float64(12),
   648  		swag.Float32(12),
   649  		swag.Float64(12),
   650  		"12",
   651  		swag.String("12"),
   652  	} {
   653  		val := anInteger
   654  		require.Truef(t, isInteger(val), "expected %#v to be detected an integer value", val)
   655  	}
   656  
   657  	for _, notAnInteger := range []interface{}{
   658  		float32(12.5),
   659  		float64(12.5),
   660  		swag.Float32(12.5),
   661  		swag.Float64(12.5),
   662  		[]string{"a"},
   663  		struct{}{},
   664  		nil,
   665  		map[string]int{"a": 1},
   666  		"abc",
   667  		"2.34",
   668  		swag.String("2.34"),
   669  		nilString,
   670  		nilInt,
   671  		nilFloat,
   672  	} {
   673  		val := notAnInteger
   674  		require.Falsef(t, isInteger(val), "did not expect %#v to be detected an integer value", val)
   675  	}
   676  }
   677  
   678  func TestGt0(t *testing.T) {
   679  	require.True(t, gt0(swag.Int64(1)))
   680  	require.False(t, gt0(swag.Int64(0)))
   681  	require.False(t, gt0(nil))
   682  }