Files
atomctl/pkg/swag/packages_test.go
2024-12-23 15:58:17 +08:00

263 lines
6.7 KiB
Go

package swag
import (
"go/ast"
"go/token"
"path/filepath"
"runtime"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPackagesDefinitions_ParseFile(t *testing.T) {
pd := PackagesDefinitions{}
packageDir := "git.ipao.vip/rogeecn/atomctl/pkg/swag/testdata/simple"
assert.NoError(t, pd.ParseFile(packageDir, "testdata/simple/main.go", nil, ParseAll))
assert.Equal(t, 1, len(pd.packages))
assert.Equal(t, 1, len(pd.files))
}
func TestPackagesDefinitions_collectAstFile(t *testing.T) {
pd := PackagesDefinitions{}
fileSet := token.NewFileSet()
assert.NoError(t, pd.collectAstFile(fileSet, "", "", nil, ParseAll))
firstFile := &ast.File{
Name: &ast.Ident{Name: "main.go"},
}
packageDir := "git.ipao.vip/rogeecn/atomctl/pkg/swag/testdata/simple"
assert.NoError(t, pd.collectAstFile(fileSet, packageDir, "testdata/simple/"+firstFile.Name.String(), firstFile, ParseAll))
assert.NotEmpty(t, pd.packages[packageDir])
absPath, _ := filepath.Abs("testdata/simple/" + firstFile.Name.String())
astFileInfo := &AstFileInfo{
FileSet: fileSet,
File: firstFile,
Path: absPath,
PackagePath: packageDir,
ParseFlag: ParseAll,
}
assert.Equal(t, pd.files[firstFile], astFileInfo)
// Override
assert.NoError(t, pd.collectAstFile(fileSet, packageDir, "testdata/simple/"+firstFile.Name.String(), firstFile, ParseAll))
assert.Equal(t, pd.files[firstFile], astFileInfo)
// Another file
secondFile := &ast.File{
Name: &ast.Ident{Name: "api.go"},
}
assert.NoError(t, pd.collectAstFile(fileSet, packageDir, "testdata/simple/"+secondFile.Name.String(), secondFile, ParseAll))
}
func TestPackagesDefinitions_rangeFiles(t *testing.T) {
pd := PackagesDefinitions{
files: map[*ast.File]*AstFileInfo{
{
Name: &ast.Ident{Name: "main.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "main.go"}},
Path: "testdata/simple/main.go",
PackagePath: "main",
},
{
Name: &ast.Ident{Name: "api.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "api.go"}},
Path: "testdata/simple/api/api.go",
PackagePath: "api",
},
},
}
i, expect := 0, []string{"testdata/simple/api/api.go", "testdata/simple/main.go"}
_ = pd.RangeFiles(func(fileInfo *AstFileInfo) error {
assert.Equal(t, expect[i], fileInfo.Path)
i++
return nil
})
}
func TestPackagesDefinitions_ParseTypes(t *testing.T) {
absPath, _ := filepath.Abs("")
mainAST := ast.File{
Name: &ast.Ident{Name: "main.go"},
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.TYPE,
Specs: []ast.Spec{
&ast.TypeSpec{
Name: &ast.Ident{Name: "Test"},
Type: &ast.Ident{
Name: "string",
},
},
},
},
},
}
pd := PackagesDefinitions{
files: map[*ast.File]*AstFileInfo{
&mainAST: {
File: &mainAST,
Path: filepath.Join(absPath, "testdata/simple/main.go"),
PackagePath: "main",
},
{
Name: &ast.Ident{Name: "api.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "api.go"}},
Path: filepath.Join(absPath, "testdata/simple/api/api.go"),
PackagePath: "api",
},
},
packages: make(map[string]*PackageDefinitions),
}
_, err := pd.ParseTypes()
assert.NoError(t, err)
}
func TestPackagesDefinitions_parseFunctionScopedTypesFromFile(t *testing.T) {
mainAST := &ast.File{
Name: &ast.Ident{Name: "main.go"},
Decls: []ast.Decl{
&ast.FuncDecl{
Name: ast.NewIdent("TestFuncDecl"),
Body: &ast.BlockStmt{
List: []ast.Stmt{
&ast.DeclStmt{
Decl: &ast.GenDecl{
Tok: token.TYPE,
Specs: []ast.Spec{
&ast.TypeSpec{
Name: ast.NewIdent("response"),
Type: ast.NewIdent("struct"),
},
&ast.TypeSpec{
Name: ast.NewIdent("stringResponse"),
Type: ast.NewIdent("string"),
},
},
},
},
},
},
},
},
}
pd := PackagesDefinitions{
packages: make(map[string]*PackageDefinitions),
}
parsedSchema := make(map[*TypeSpecDef]*Schema)
pd.parseFunctionScopedTypesFromFile(mainAST, "main", parsedSchema)
assert.Len(t, parsedSchema, 1)
_, ok := pd.uniqueDefinitions["main.go.TestFuncDecl.response"]
assert.True(t, ok)
_, ok = pd.packages["main"].TypeDefinitions["main.go.TestFuncDecl.response"]
assert.True(t, ok)
}
func TestPackagesDefinitions_FindTypeSpec(t *testing.T) {
userDef := TypeSpecDef{
File: &ast.File{
Name: &ast.Ident{Name: "user.go"},
},
TypeSpec: &ast.TypeSpec{
Name: ast.NewIdent("User"),
},
PkgPath: "user",
}
pkg := PackagesDefinitions{
uniqueDefinitions: map[string]*TypeSpecDef{
"user.Model": &userDef,
},
}
var nilDef *TypeSpecDef
assert.Equal(t, nilDef, pkg.FindTypeSpec("int", nil))
assert.Equal(t, nilDef, pkg.FindTypeSpec("bool", nil))
assert.Equal(t, nilDef, pkg.FindTypeSpec("string", nil))
assert.Equal(t, &userDef, pkg.FindTypeSpec("user.Model", nil))
assert.Equal(t, nilDef, pkg.FindTypeSpec("Model", nil))
}
func TestPackage_rangeFiles(t *testing.T) {
pd := NewPackagesDefinitions()
pd.files = map[*ast.File]*AstFileInfo{
{
Name: &ast.Ident{Name: "main.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "main.go"}},
Path: "testdata/simple/main.go",
PackagePath: "main",
},
{
Name: &ast.Ident{Name: "api.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "api.go"}},
Path: "testdata/simple/api/api.go",
PackagePath: "api",
},
{
Name: &ast.Ident{Name: "foo.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "foo.go"}},
Path: "vendor/foo/foo.go",
PackagePath: "vendor/foo",
},
{
Name: &ast.Ident{Name: "bar.go"},
}: {
File: &ast.File{Name: &ast.Ident{Name: "bar.go"}},
Path: filepath.Join(runtime.GOROOT(), "bar.go"),
PackagePath: "bar",
},
}
var sorted []string
processor := func(fileInfo *AstFileInfo) error {
sorted = append(sorted, fileInfo.Path)
return nil
}
assert.NoError(t, pd.RangeFiles(processor))
assert.Equal(t, []string{"testdata/simple/api/api.go", "testdata/simple/main.go"}, sorted)
assert.Error(t, pd.RangeFiles(func(fileInfo *AstFileInfo) error {
return ErrFuncTypeField
}))
}
func TestPackagesDefinitions_findTypeSpec(t *testing.T) {
pd := PackagesDefinitions{}
var nilTypeSpec *TypeSpecDef
assert.Equal(t, nilTypeSpec, pd.findTypeSpec("model", "User"))
userTypeSpec := TypeSpecDef{
File: &ast.File{},
TypeSpec: &ast.TypeSpec{},
PkgPath: "model",
}
pd = PackagesDefinitions{
packages: map[string]*PackageDefinitions{
"model": {
TypeDefinitions: map[string]*TypeSpecDef{
"User": &userTypeSpec,
},
},
},
}
assert.Equal(t, &userTypeSpec, pd.findTypeSpec("model", "User"))
assert.Equal(t, nilTypeSpec, pd.findTypeSpec("others", "User"))
}