From 4927c2a9321bbca23799e26fe1a750e2c15d41f5 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 15:01:11 +0100 Subject: [PATCH 01/32] Add naive file getting --- .../acceptance_tests_arch_check_test.go | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 pkg/archtests/acceptance_tests_arch_check_test.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go new file mode 100644 index 0000000000..6292ac1f24 --- /dev/null +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -0,0 +1,23 @@ +package archtests + +import ( + "fmt" + "go/parser" + "go/token" + "testing" + + "github.com/stretchr/testify/require" +) + +// get all files from package +// filter all files ending with _acceptance_test.go +// check all exported methods start with TestAcc_ +// list all failing methods +func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { + path := "../resources/" + packagesDict, err := parser.ParseDir(token.NewFileSet(), path, nil, 0) + require.NoError(t, err) + fmt.Printf("%v", packagesDict) + fmt.Printf("%v", packagesDict["resources"]) + fmt.Printf("%v", packagesDict["resources_test"]) +} From 434b2068f68b2e765cbb197bb04bf2b779ccc167 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 16:11:16 +0100 Subject: [PATCH 02/32] Test naively (resources) --- .../acceptance_tests_arch_check_test.go | 59 +++++++++++++++---- .../database_grant_acceptance_test.go | 2 +- pkg/resources/role_grants_acceptance_test.go | 6 +- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 6292ac1f24..5469fe1d62 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -1,23 +1,62 @@ package archtests import ( - "fmt" + "go/ast" "go/parser" "go/token" + "io/fs" + "regexp" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// get all files from package -// filter all files ending with _acceptance_test.go -// check all exported methods start with TestAcc_ -// list all failing methods func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { - path := "../resources/" - packagesDict, err := parser.ParseDir(token.NewFileSet(), path, nil, 0) + resourcesPath := "../resources/" + acceptanceTestFileRegex, err := regexp.Compile("^.*_acceptance_test.go$") require.NoError(t, err) - fmt.Printf("%v", packagesDict) - fmt.Printf("%v", packagesDict["resources"]) - fmt.Printf("%v", packagesDict["resources_test"]) + acceptanceTestFileNameRegex, err := regexp.Compile("^TestAcc_.*$") + + t.Run("acceptance tests for resources have the right package", func(t *testing.T) { + packagesDict, err := parser.ParseDir(token.NewFileSet(), resourcesPath, fileNameFilterProvider(acceptanceTestFileRegex), 0) + require.NoError(t, err) + + assert.Len(t, packagesDict, 1) + assert.Contains(t, packagesDict, "resources_test") + assert.NotContains(t, packagesDict, "resources") + }) + + t.Run("acceptance tests are named correctly", func(t *testing.T) { + packagesDict, err := parser.ParseDir(token.NewFileSet(), resourcesPath, fileNameFilterProvider(acceptanceTestFileRegex), 0) + require.NoError(t, err) + + allMatchingFiles := packagesDict["resources_test"].Files + for name, src := range allMatchingFiles { + exportedMethods := allExportedMethodsInFile(src) + for _, method := range exportedMethods { + assert.Truef(t, acceptanceTestFileNameRegex.Match([]byte(method)), "filename %s contains exported method %s which does not match %s", name, method, acceptanceTestFileNameRegex.String()) + } + } + }) +} + +func fileNameFilterProvider(regex *regexp.Regexp) func(fi fs.FileInfo) bool { + return func(fi fs.FileInfo) bool { + return regex.Match([]byte(fi.Name())) + } +} + +func allExportedMethodsInFile(src *ast.File) []string { + allExportedMethods := make([]string, 0) + for _, d := range src.Decls { + switch d.(type) { + case *ast.FuncDecl: + name := d.(*ast.FuncDecl).Name.Name + if ast.IsExported(name) { + allExportedMethods = append(allExportedMethods, name) + } + } + } + return allExportedMethods } diff --git a/pkg/resources/database_grant_acceptance_test.go b/pkg/resources/database_grant_acceptance_test.go index 1bb7e9e040..55de7bf4c3 100644 --- a/pkg/resources/database_grant_acceptance_test.go +++ b/pkg/resources/database_grant_acceptance_test.go @@ -16,7 +16,7 @@ func testRolesAndShares(t *testing.T, path string, roles []string) func(*terrafo return func(state *terraform.State) error { is := state.RootModule().Resources[path].Primary - if c, ok := is.Attributes["roles.#"]; !ok || MustParseInt(t, c) != int64(len(roles)) { + if c, ok := is.Attributes["roles.#"]; !ok || mustParseInt(t, c) != int64(len(roles)) { return fmt.Errorf("expected roles.# to equal %d but got %s", len(roles), c) } r, err := extractList(is.Attributes, "roles") diff --git a/pkg/resources/role_grants_acceptance_test.go b/pkg/resources/role_grants_acceptance_test.go index 8bb7f0f403..0c143abd6a 100644 --- a/pkg/resources/role_grants_acceptance_test.go +++ b/pkg/resources/role_grants_acceptance_test.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/terraform" ) -func MustParseInt(t *testing.T, input string) int64 { +func mustParseInt(t *testing.T, input string) int64 { t.Helper() i, err := strconv.ParseInt(input, 10, 64) if err != nil { @@ -61,7 +61,7 @@ func testCheckRolesAndUsers(t *testing.T, path string, roles, users []string) fu t.Helper() return func(state *terraform.State) error { is := state.RootModule().Resources[path].Primary - if c, ok := is.Attributes["roles.#"]; !ok || MustParseInt(t, c) != int64(len(roles)) { + if c, ok := is.Attributes["roles.#"]; !ok || mustParseInt(t, c) != int64(len(roles)) { return fmt.Errorf("expected roles.# to equal %d but got %s", len(roles), c) } r, err := extractList(is.Attributes, "roles") @@ -74,7 +74,7 @@ func testCheckRolesAndUsers(t *testing.T, path string, roles, users []string) fu return fmt.Errorf("expected roles %#v but got %#v", roles, r) } - if c, ok := is.Attributes["users.#"]; !ok || MustParseInt(t, c) != int64(len(users)) { + if c, ok := is.Attributes["users.#"]; !ok || mustParseInt(t, c) != int64(len(users)) { return fmt.Errorf("expected users.# to equal %d but got %s", len(users), c) } u, err := extractList(is.Attributes, "users") From 3391f46388ffc828b93b75dbb42ba674e895aa2d Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:22:11 +0100 Subject: [PATCH 03/32] Split into files --- .../acceptance_tests_arch_check_test.go | 66 +++++------- pkg/archtests/arch_check_assertions.go | 32 ++++++ pkg/archtests/arch_check_helpers.go | 102 ++++++++++++++++++ 3 files changed, 162 insertions(+), 38 deletions(-) create mode 100644 pkg/archtests/arch_check_assertions.go create mode 100644 pkg/archtests/arch_check_helpers.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 5469fe1d62..2c00c365bb 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -1,62 +1,52 @@ package archtests import ( - "go/ast" - "go/parser" - "go/token" - "io/fs" - "regexp" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { resourcesPath := "../resources/" - acceptanceTestFileRegex, err := regexp.Compile("^.*_acceptance_test.go$") + resourcesFiles, err := filesInDirectory(resourcesPath, nil) require.NoError(t, err) - acceptanceTestFileNameRegex, err := regexp.Compile("^TestAcc_.*$") - t.Run("acceptance tests for resources have the right package", func(t *testing.T) { - packagesDict, err := parser.ParseDir(token.NewFileSet(), resourcesPath, fileNameFilterProvider(acceptanceTestFileRegex), 0) - require.NoError(t, err) + t.Run("acceptance tests files have the right package", func(t *testing.T) { + acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - assert.Len(t, packagesDict, 1) - assert.Contains(t, packagesDict, "resources_test") - assert.NotContains(t, packagesDict, "resources") + for _, file := range acceptanceTestFiles { + assertPackage(t, &file, "resources_test") + } }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - packagesDict, err := parser.ParseDir(token.NewFileSet(), resourcesPath, fileNameFilterProvider(acceptanceTestFileRegex), 0) - require.NoError(t, err) - - allMatchingFiles := packagesDict["resources_test"].Files - for name, src := range allMatchingFiles { - exportedMethods := allExportedMethodsInFile(src) - for _, method := range exportedMethods { - assert.Truef(t, acceptanceTestFileNameRegex.Match([]byte(method)), "filename %s contains exported method %s which does not match %s", name, method, acceptanceTestFileNameRegex.String()) + acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) + + for _, file := range acceptanceTestFiles { + for _, method := range allExportedMethodsInFile(file.fileSrc) { + assertAcceptanceTestNamedCorrectly(t, &file, method) } } }) -} -func fileNameFilterProvider(regex *regexp.Regexp) func(fi fs.FileInfo) bool { - return func(fi fs.FileInfo) bool { - return regex.Match([]byte(fi.Name())) - } -} + t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := filterFiles(resourcesFiles, fileNameFilterWithExclusionsProvider(testFileRegex, acceptanceTestFileRegex)) + + for _, file := range otherTestFiles { + for _, method := range allExportedMethodsInFile(file.fileSrc) { + assertMethodNameDoesNotMatch(t, &file, method, acceptanceTestNameRegex) + } + } + }) -func allExportedMethodsInFile(src *ast.File) []string { - allExportedMethods := make([]string, 0) - for _, d := range src.Decls { - switch d.(type) { - case *ast.FuncDecl: - name := d.(*ast.FuncDecl).Name.Name - if ast.IsExported(name) { - allExportedMethods = append(allExportedMethods, name) + t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { + t.Skipf("Currently there are non-acceptance tests in resources_test package") + packageFiles := filterFiles(resourcesFiles, packageFilterProvider("resources_test")) + + for _, file := range packageFiles { + for _, method := range allExportedMethodsInFile(file.fileSrc) { + assertAcceptanceTestNamedCorrectly(t, &file, method) } } - } - return allExportedMethods + }) } diff --git a/pkg/archtests/arch_check_assertions.go b/pkg/archtests/arch_check_assertions.go new file mode 100644 index 0000000000..a03d1b3976 --- /dev/null +++ b/pkg/archtests/arch_check_assertions.go @@ -0,0 +1,32 @@ +package archtests + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" +) + +func assertPackage(t *testing.T, f *File, expectedPackage string) { + assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) +} + +func assertAcceptanceTestNamedCorrectly(t *testing.T, f *File, methodName string) { + assertMethodNameMatches(t, f, methodName, acceptanceTestNameRegex) +} + +func assertMethodNameMatches(t *testing.T, f *File, methodName string, regex *regexp.Regexp) { + assert.Truef(t, regex.MatchString(methodName), "filename %s contains exported method %s which does not match %s", f.fileName, methodName, regex.String()) +} + +func assertMethodNameDoesNotMatch(t *testing.T, f *File, methodName string, regex *regexp.Regexp) { + assert.Falsef(t, regex.MatchString(methodName), "filename %s contains exported method %s which matches %s", f.fileName, methodName, regex.String()) +} + +//func assertMethodNameMatchesExcluding(t *testing.T, f *File, methodName string, regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) { +// matches := regex.MatchString(methodName) +// for _, e := range exclusionRegex { +// matches = matches && !e.MatchString(methodName) +// } +// assert.Truef(t, matches, "filename %s contains exported method %s which does not match given combination of regexps", f.fileName, methodName) +//} diff --git a/pkg/archtests/arch_check_helpers.go b/pkg/archtests/arch_check_helpers.go new file mode 100644 index 0000000000..3ed0619763 --- /dev/null +++ b/pkg/archtests/arch_check_helpers.go @@ -0,0 +1,102 @@ +package archtests + +import ( + "go/ast" + "go/parser" + "go/token" + "io/fs" + "regexp" +) + +var ( + acceptanceTestFileRegex *regexp.Regexp + acceptanceTestNameRegex *regexp.Regexp + testFileRegex *regexp.Regexp + testNameRegex *regexp.Regexp +) + +func init() { + var err error + acceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") + if err != nil { + panic(err) + } + acceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") + if err != nil { + panic(err) + } + testFileRegex, err = regexp.Compile("^.*_test.go$") + if err != nil { + panic(err) + } + testNameRegex, err = regexp.Compile("^Test.*$") + if err != nil { + panic(err) + } +} + +type File struct { + packageName string + fileName string + fileSrc *ast.File +} + +func filesInDirectory(path string, filter func(fi fs.FileInfo) bool) ([]File, error) { + packagesDict, err := parser.ParseDir(token.NewFileSet(), path, filter, 0) + if err != nil { + return nil, err + } + files := make([]File, 0) + for packageName, astPackage := range packagesDict { + for fileName, fileSrc := range astPackage.Files { + files = append(files, File{packageName, fileName, fileSrc}) + } + } + return files, nil +} + +func filterFiles(files []File, filter func(*File) bool) []File { + filteredFiles := make([]File, 0) + for _, f := range files { + if filter(&f) { + filteredFiles = append(filteredFiles, f) + } + } + return filteredFiles +} + +func fileNameFilterProvider(regex *regexp.Regexp) func(f *File) bool { + return func(f *File) bool { + return regex.Match([]byte(f.fileName)) + } +} + +func fileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) func(f *File) bool { + return func(f *File) bool { + matches := regex.MatchString(f.fileName) + for _, e := range exclusionRegex { + matches = matches && !e.MatchString(f.fileName) + } + return matches + } +} + +func packageFilterProvider(packageName string) func(f *File) bool { + return func(f *File) bool { + return f.packageName == packageName + } +} + +func allExportedMethodsInFile(src *ast.File) []string { + allExportedMethods := make([]string, 0) + for _, d := range src.Decls { + switch d.(type) { + case *ast.FuncDecl: + name := d.(*ast.FuncDecl).Name.Name + if ast.IsExported(name) { + allExportedMethods = append(allExportedMethods, name) + } + } + } + return allExportedMethods +} From 267de70be8e72e7f9e1e26171cd027f8c5e8a670 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:26:48 +0100 Subject: [PATCH 04/32] Add assertion for non-acceptance tests --- pkg/archtests/acceptance_tests_arch_check_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 2c00c365bb..178348bcf2 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -35,6 +35,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { for _, file := range otherTestFiles { for _, method := range allExportedMethodsInFile(file.fileSrc) { assertMethodNameDoesNotMatch(t, &file, method, acceptanceTestNameRegex) + assertMethodNameMatches(t, &file, method, testNameRegex) } } }) From 2d0ffb60348c04856b4baf33744a19318272d08c Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:34:14 +0100 Subject: [PATCH 05/32] Reorganize --- .../acceptance_tests_arch_check_test.go | 8 +- pkg/archtests/arch_check_helpers.go | 102 ------------------ ...arch_check_assertions.go => assertions.go} | 0 pkg/archtests/directory_filters.go | 25 +++++ pkg/archtests/file.go | 53 +++++++++ pkg/archtests/file_filters.go | 37 +++++++ 6 files changed, 119 insertions(+), 106 deletions(-) delete mode 100644 pkg/archtests/arch_check_helpers.go rename pkg/archtests/{arch_check_assertions.go => assertions.go} (100%) create mode 100644 pkg/archtests/directory_filters.go create mode 100644 pkg/archtests/file.go create mode 100644 pkg/archtests/file_filters.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 178348bcf2..d9f8266fac 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -8,7 +8,7 @@ import ( func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { resourcesPath := "../resources/" - resourcesFiles, err := filesInDirectory(resourcesPath, nil) + resourcesFiles, err := allFilesInDirectory(resourcesPath) require.NoError(t, err) t.Run("acceptance tests files have the right package", func(t *testing.T) { @@ -23,7 +23,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) for _, file := range acceptanceTestFiles { - for _, method := range allExportedMethodsInFile(file.fileSrc) { + for _, method := range file.allExportedMethods() { assertAcceptanceTestNamedCorrectly(t, &file, method) } } @@ -33,7 +33,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { otherTestFiles := filterFiles(resourcesFiles, fileNameFilterWithExclusionsProvider(testFileRegex, acceptanceTestFileRegex)) for _, file := range otherTestFiles { - for _, method := range allExportedMethodsInFile(file.fileSrc) { + for _, method := range file.allExportedMethods() { assertMethodNameDoesNotMatch(t, &file, method, acceptanceTestNameRegex) assertMethodNameMatches(t, &file, method, testNameRegex) } @@ -45,7 +45,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { packageFiles := filterFiles(resourcesFiles, packageFilterProvider("resources_test")) for _, file := range packageFiles { - for _, method := range allExportedMethodsInFile(file.fileSrc) { + for _, method := range file.allExportedMethods() { assertAcceptanceTestNamedCorrectly(t, &file, method) } } diff --git a/pkg/archtests/arch_check_helpers.go b/pkg/archtests/arch_check_helpers.go deleted file mode 100644 index 3ed0619763..0000000000 --- a/pkg/archtests/arch_check_helpers.go +++ /dev/null @@ -1,102 +0,0 @@ -package archtests - -import ( - "go/ast" - "go/parser" - "go/token" - "io/fs" - "regexp" -) - -var ( - acceptanceTestFileRegex *regexp.Regexp - acceptanceTestNameRegex *regexp.Regexp - testFileRegex *regexp.Regexp - testNameRegex *regexp.Regexp -) - -func init() { - var err error - acceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") - if err != nil { - panic(err) - } - acceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") - if err != nil { - panic(err) - } - testFileRegex, err = regexp.Compile("^.*_test.go$") - if err != nil { - panic(err) - } - testNameRegex, err = regexp.Compile("^Test.*$") - if err != nil { - panic(err) - } -} - -type File struct { - packageName string - fileName string - fileSrc *ast.File -} - -func filesInDirectory(path string, filter func(fi fs.FileInfo) bool) ([]File, error) { - packagesDict, err := parser.ParseDir(token.NewFileSet(), path, filter, 0) - if err != nil { - return nil, err - } - files := make([]File, 0) - for packageName, astPackage := range packagesDict { - for fileName, fileSrc := range astPackage.Files { - files = append(files, File{packageName, fileName, fileSrc}) - } - } - return files, nil -} - -func filterFiles(files []File, filter func(*File) bool) []File { - filteredFiles := make([]File, 0) - for _, f := range files { - if filter(&f) { - filteredFiles = append(filteredFiles, f) - } - } - return filteredFiles -} - -func fileNameFilterProvider(regex *regexp.Regexp) func(f *File) bool { - return func(f *File) bool { - return regex.Match([]byte(f.fileName)) - } -} - -func fileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) func(f *File) bool { - return func(f *File) bool { - matches := regex.MatchString(f.fileName) - for _, e := range exclusionRegex { - matches = matches && !e.MatchString(f.fileName) - } - return matches - } -} - -func packageFilterProvider(packageName string) func(f *File) bool { - return func(f *File) bool { - return f.packageName == packageName - } -} - -func allExportedMethodsInFile(src *ast.File) []string { - allExportedMethods := make([]string, 0) - for _, d := range src.Decls { - switch d.(type) { - case *ast.FuncDecl: - name := d.(*ast.FuncDecl).Name.Name - if ast.IsExported(name) { - allExportedMethods = append(allExportedMethods, name) - } - } - } - return allExportedMethods -} diff --git a/pkg/archtests/arch_check_assertions.go b/pkg/archtests/assertions.go similarity index 100% rename from pkg/archtests/arch_check_assertions.go rename to pkg/archtests/assertions.go diff --git a/pkg/archtests/directory_filters.go b/pkg/archtests/directory_filters.go new file mode 100644 index 0000000000..191d653e95 --- /dev/null +++ b/pkg/archtests/directory_filters.go @@ -0,0 +1,25 @@ +package archtests + +import ( + "go/parser" + "go/token" + "io/fs" +) + +func allFilesInDirectory(path string) ([]File, error) { + return filesInDirectory(path, nil) +} + +func filesInDirectory(path string, filter func(fi fs.FileInfo) bool) ([]File, error) { + packagesDict, err := parser.ParseDir(token.NewFileSet(), path, filter, 0) + if err != nil { + return nil, err + } + files := make([]File, 0) + for packageName, astPackage := range packagesDict { + for fileName, fileSrc := range astPackage.Files { + files = append(files, File{packageName, fileName, fileSrc}) + } + } + return files, nil +} diff --git a/pkg/archtests/file.go b/pkg/archtests/file.go new file mode 100644 index 0000000000..2fbb8ad590 --- /dev/null +++ b/pkg/archtests/file.go @@ -0,0 +1,53 @@ +package archtests + +import ( + "go/ast" + "regexp" +) + +var ( + acceptanceTestFileRegex *regexp.Regexp + acceptanceTestNameRegex *regexp.Regexp + testFileRegex *regexp.Regexp + testNameRegex *regexp.Regexp +) + +func init() { + var err error + acceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") + if err != nil { + panic(err) + } + acceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") + if err != nil { + panic(err) + } + testFileRegex, err = regexp.Compile("^.*_test.go$") + if err != nil { + panic(err) + } + testNameRegex, err = regexp.Compile("^Test.*$") + if err != nil { + panic(err) + } +} + +type File struct { + packageName string + fileName string + fileSrc *ast.File +} + +func (f *File) allExportedMethods() []string { + allExportedMethods := make([]string, 0) + for _, d := range f.fileSrc.Decls { + switch d.(type) { + case *ast.FuncDecl: + name := d.(*ast.FuncDecl).Name.Name + if ast.IsExported(name) { + allExportedMethods = append(allExportedMethods, name) + } + } + } + return allExportedMethods +} diff --git a/pkg/archtests/file_filters.go b/pkg/archtests/file_filters.go new file mode 100644 index 0000000000..eda0a5c679 --- /dev/null +++ b/pkg/archtests/file_filters.go @@ -0,0 +1,37 @@ +package archtests + +import "regexp" + +type FileFilter = func(*File) bool + +func filterFiles(files []File, filter FileFilter) []File { + filteredFiles := make([]File, 0) + for _, f := range files { + if filter(&f) { + filteredFiles = append(filteredFiles, f) + } + } + return filteredFiles +} + +func fileNameFilterProvider(regex *regexp.Regexp) FileFilter { + return func(f *File) bool { + return regex.Match([]byte(f.fileName)) + } +} + +func fileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) FileFilter { + return func(f *File) bool { + matches := regex.MatchString(f.fileName) + for _, e := range exclusionRegex { + matches = matches && !e.MatchString(f.fileName) + } + return matches + } +} + +func packageFilterProvider(packageName string) FileFilter { + return func(f *File) bool { + return f.packageName == packageName + } +} From 7575186649f038d5e3cf37d945a091858db2a8ce Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:45:51 +0100 Subject: [PATCH 06/32] Extract files --- .../acceptance_tests_arch_check_test.go | 32 +++++++++---------- pkg/archtests/assertions.go | 8 ----- ...le_filters.go => file_filter_providers.go} | 12 ------- pkg/archtests/files.go | 20 ++++++++++++ 4 files changed, 36 insertions(+), 36 deletions(-) rename pkg/archtests/{file_filters.go => file_filter_providers.go} (70%) create mode 100644 pkg/archtests/files.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index d9f8266fac..72e05a6210 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -14,40 +14,40 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { t.Run("acceptance tests files have the right package", func(t *testing.T) { acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - for _, file := range acceptanceTestFiles { - assertPackage(t, &file, "resources_test") - } + iterateFiles(acceptanceTestFiles, func(f *File) { + assertPackage(t, f, "resources_test") + }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - for _, file := range acceptanceTestFiles { - for _, method := range file.allExportedMethods() { - assertAcceptanceTestNamedCorrectly(t, &file, method) + iterateFiles(acceptanceTestFiles, func(f *File) { + for _, method := range f.allExportedMethods() { + assertAcceptanceTestNamedCorrectly(t, f, method) } - } + }) }) t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { otherTestFiles := filterFiles(resourcesFiles, fileNameFilterWithExclusionsProvider(testFileRegex, acceptanceTestFileRegex)) - for _, file := range otherTestFiles { - for _, method := range file.allExportedMethods() { - assertMethodNameDoesNotMatch(t, &file, method, acceptanceTestNameRegex) - assertMethodNameMatches(t, &file, method, testNameRegex) + iterateFiles(otherTestFiles, func(f *File) { + for _, method := range f.allExportedMethods() { + assertMethodNameDoesNotMatch(t, f, method, acceptanceTestNameRegex) + assertMethodNameMatches(t, f, method, testNameRegex) } - } + }) }) t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { t.Skipf("Currently there are non-acceptance tests in resources_test package") packageFiles := filterFiles(resourcesFiles, packageFilterProvider("resources_test")) - for _, file := range packageFiles { - for _, method := range file.allExportedMethods() { - assertAcceptanceTestNamedCorrectly(t, &file, method) + iterateFiles(packageFiles, func(f *File) { + for _, method := range f.allExportedMethods() { + assertAcceptanceTestNamedCorrectly(t, f, method) } - } + }) }) } diff --git a/pkg/archtests/assertions.go b/pkg/archtests/assertions.go index a03d1b3976..d362e3b7da 100644 --- a/pkg/archtests/assertions.go +++ b/pkg/archtests/assertions.go @@ -22,11 +22,3 @@ func assertMethodNameMatches(t *testing.T, f *File, methodName string, regex *re func assertMethodNameDoesNotMatch(t *testing.T, f *File, methodName string, regex *regexp.Regexp) { assert.Falsef(t, regex.MatchString(methodName), "filename %s contains exported method %s which matches %s", f.fileName, methodName, regex.String()) } - -//func assertMethodNameMatchesExcluding(t *testing.T, f *File, methodName string, regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) { -// matches := regex.MatchString(methodName) -// for _, e := range exclusionRegex { -// matches = matches && !e.MatchString(methodName) -// } -// assert.Truef(t, matches, "filename %s contains exported method %s which does not match given combination of regexps", f.fileName, methodName) -//} diff --git a/pkg/archtests/file_filters.go b/pkg/archtests/file_filter_providers.go similarity index 70% rename from pkg/archtests/file_filters.go rename to pkg/archtests/file_filter_providers.go index eda0a5c679..3ff85dcadc 100644 --- a/pkg/archtests/file_filters.go +++ b/pkg/archtests/file_filter_providers.go @@ -2,18 +2,6 @@ package archtests import "regexp" -type FileFilter = func(*File) bool - -func filterFiles(files []File, filter FileFilter) []File { - filteredFiles := make([]File, 0) - for _, f := range files { - if filter(&f) { - filteredFiles = append(filteredFiles, f) - } - } - return filteredFiles -} - func fileNameFilterProvider(regex *regexp.Regexp) FileFilter { return func(f *File) bool { return regex.Match([]byte(f.fileName)) diff --git a/pkg/archtests/files.go b/pkg/archtests/files.go new file mode 100644 index 0000000000..841097dd3c --- /dev/null +++ b/pkg/archtests/files.go @@ -0,0 +1,20 @@ +package archtests + +type FileFilter = func(*File) bool +type FileReceiver = func(*File) + +func filterFiles(files []File, filter FileFilter) []File { + filteredFiles := make([]File, 0) + for _, f := range files { + if filter(&f) { + filteredFiles = append(filteredFiles, f) + } + } + return filteredFiles +} + +func iterateFiles(files []File, receiver FileReceiver) { + for _, file := range files { + receiver(&file) + } +} From fe584a014c59d17509c4d7da91dd6f1653d66953 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:51:51 +0100 Subject: [PATCH 07/32] Extract directory --- .../acceptance_tests_arch_check_test.go | 4 +-- pkg/archtests/directory.go | 33 +++++++++++++++++++ pkg/archtests/directory_filters.go | 25 -------------- pkg/archtests/file.go | 8 +++++ 4 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 pkg/archtests/directory.go delete mode 100644 pkg/archtests/directory_filters.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 72e05a6210..363c8df41a 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -7,8 +7,8 @@ import ( ) func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { - resourcesPath := "../resources/" - resourcesFiles, err := allFilesInDirectory(resourcesPath) + resourcesDirectory := NewDirectory("../resources/") + resourcesFiles, err := resourcesDirectory.allFiles() require.NoError(t, err) t.Run("acceptance tests files have the right package", func(t *testing.T) { diff --git a/pkg/archtests/directory.go b/pkg/archtests/directory.go new file mode 100644 index 0000000000..ef7e769a6d --- /dev/null +++ b/pkg/archtests/directory.go @@ -0,0 +1,33 @@ +package archtests + +import ( + "go/parser" + "go/token" + "io/fs" +) + +type Directory struct { + path string +} + +func NewDirectory(path string) *Directory { + return &Directory{path: path} +} + +func (d *Directory) allFiles() ([]File, error) { + return d.files(nil) +} + +func (d *Directory) files(filter func(fi fs.FileInfo) bool) ([]File, error) { + packagesDict, err := parser.ParseDir(token.NewFileSet(), d.path, filter, 0) + if err != nil { + return nil, err + } + files := make([]File, 0) + for packageName, astPackage := range packagesDict { + for fileName, fileSrc := range astPackage.Files { + files = append(files, *NewFile(packageName, fileName, fileSrc)) + } + } + return files, nil +} diff --git a/pkg/archtests/directory_filters.go b/pkg/archtests/directory_filters.go deleted file mode 100644 index 191d653e95..0000000000 --- a/pkg/archtests/directory_filters.go +++ /dev/null @@ -1,25 +0,0 @@ -package archtests - -import ( - "go/parser" - "go/token" - "io/fs" -) - -func allFilesInDirectory(path string) ([]File, error) { - return filesInDirectory(path, nil) -} - -func filesInDirectory(path string, filter func(fi fs.FileInfo) bool) ([]File, error) { - packagesDict, err := parser.ParseDir(token.NewFileSet(), path, filter, 0) - if err != nil { - return nil, err - } - files := make([]File, 0) - for packageName, astPackage := range packagesDict { - for fileName, fileSrc := range astPackage.Files { - files = append(files, File{packageName, fileName, fileSrc}) - } - } - return files, nil -} diff --git a/pkg/archtests/file.go b/pkg/archtests/file.go index 2fbb8ad590..1d484d8b36 100644 --- a/pkg/archtests/file.go +++ b/pkg/archtests/file.go @@ -38,6 +38,14 @@ type File struct { fileSrc *ast.File } +func NewFile(packageName string, fileName string, fileSrc *ast.File) *File { + return &File{ + packageName: packageName, + fileName: fileName, + fileSrc: fileSrc, + } +} + func (f *File) allExportedMethods() []string { allExportedMethods := make([]string, 0) for _, d := range f.fileSrc.Decls { From 12194681abe7cf266d11279f63a3d45a03ec5b02 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 17:59:07 +0100 Subject: [PATCH 08/32] Extract method --- .../acceptance_tests_arch_check_test.go | 30 +++++++++---------- pkg/archtests/assertions.go | 12 ++++---- pkg/archtests/file.go | 6 ++-- pkg/archtests/method.go | 11 +++++++ pkg/archtests/methods.go | 9 ++++++ 5 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 pkg/archtests/method.go create mode 100644 pkg/archtests/methods.go diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go index 363c8df41a..58ceb97480 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -14,29 +14,29 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { t.Run("acceptance tests files have the right package", func(t *testing.T) { acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - iterateFiles(acceptanceTestFiles, func(f *File) { - assertPackage(t, f, "resources_test") + iterateFiles(acceptanceTestFiles, func(file *File) { + assertPackage(t, file, "resources_test") }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - iterateFiles(acceptanceTestFiles, func(f *File) { - for _, method := range f.allExportedMethods() { - assertAcceptanceTestNamedCorrectly(t, f, method) - } + iterateFiles(acceptanceTestFiles, func(file *File) { + iterateMethods(file.allExportedMethods(), func(method *Method) { + assertAcceptanceTestNamedCorrectly(t, file, method) + }) }) }) t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { otherTestFiles := filterFiles(resourcesFiles, fileNameFilterWithExclusionsProvider(testFileRegex, acceptanceTestFileRegex)) - iterateFiles(otherTestFiles, func(f *File) { - for _, method := range f.allExportedMethods() { - assertMethodNameDoesNotMatch(t, f, method, acceptanceTestNameRegex) - assertMethodNameMatches(t, f, method, testNameRegex) - } + iterateFiles(otherTestFiles, func(file *File) { + iterateMethods(file.allExportedMethods(), func(method *Method) { + assertMethodNameDoesNotMatch(t, file, method, acceptanceTestNameRegex) + assertMethodNameMatches(t, file, method, testNameRegex) + }) }) }) @@ -44,10 +44,10 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { t.Skipf("Currently there are non-acceptance tests in resources_test package") packageFiles := filterFiles(resourcesFiles, packageFilterProvider("resources_test")) - iterateFiles(packageFiles, func(f *File) { - for _, method := range f.allExportedMethods() { - assertAcceptanceTestNamedCorrectly(t, f, method) - } + iterateFiles(packageFiles, func(file *File) { + iterateMethods(file.allExportedMethods(), func(method *Method) { + assertAcceptanceTestNamedCorrectly(t, file, method) + }) }) }) } diff --git a/pkg/archtests/assertions.go b/pkg/archtests/assertions.go index d362e3b7da..132ec605df 100644 --- a/pkg/archtests/assertions.go +++ b/pkg/archtests/assertions.go @@ -11,14 +11,14 @@ func assertPackage(t *testing.T, f *File, expectedPackage string) { assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) } -func assertAcceptanceTestNamedCorrectly(t *testing.T, f *File, methodName string) { - assertMethodNameMatches(t, f, methodName, acceptanceTestNameRegex) +func assertAcceptanceTestNamedCorrectly(t *testing.T, f *File, method *Method) { + assertMethodNameMatches(t, f, method, acceptanceTestNameRegex) } -func assertMethodNameMatches(t *testing.T, f *File, methodName string, regex *regexp.Regexp) { - assert.Truef(t, regex.MatchString(methodName), "filename %s contains exported method %s which does not match %s", f.fileName, methodName, regex.String()) +func assertMethodNameMatches(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { + assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", f.fileName, method.name, regex.String()) } -func assertMethodNameDoesNotMatch(t *testing.T, f *File, methodName string, regex *regexp.Regexp) { - assert.Falsef(t, regex.MatchString(methodName), "filename %s contains exported method %s which matches %s", f.fileName, methodName, regex.String()) +func assertMethodNameDoesNotMatch(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { + assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", f.fileName, method.name, regex.String()) } diff --git a/pkg/archtests/file.go b/pkg/archtests/file.go index 1d484d8b36..70d5d7fa35 100644 --- a/pkg/archtests/file.go +++ b/pkg/archtests/file.go @@ -46,14 +46,14 @@ func NewFile(packageName string, fileName string, fileSrc *ast.File) *File { } } -func (f *File) allExportedMethods() []string { - allExportedMethods := make([]string, 0) +func (f *File) allExportedMethods() []Method { + allExportedMethods := make([]Method, 0) for _, d := range f.fileSrc.Decls { switch d.(type) { case *ast.FuncDecl: name := d.(*ast.FuncDecl).Name.Name if ast.IsExported(name) { - allExportedMethods = append(allExportedMethods, name) + allExportedMethods = append(allExportedMethods, *NewMethod(name)) } } } diff --git a/pkg/archtests/method.go b/pkg/archtests/method.go new file mode 100644 index 0000000000..1d98d59a02 --- /dev/null +++ b/pkg/archtests/method.go @@ -0,0 +1,11 @@ +package archtests + +type Method struct { + name string +} + +func NewMethod(name string) *Method { + return &Method{ + name: name, + } +} diff --git a/pkg/archtests/methods.go b/pkg/archtests/methods.go new file mode 100644 index 0000000000..adbb3f158f --- /dev/null +++ b/pkg/archtests/methods.go @@ -0,0 +1,9 @@ +package archtests + +type MethodReceiver = func(method *Method) + +func iterateMethods(methods []Method, receiver MethodReceiver) { + for _, method := range methods { + receiver(&method) + } +} From 8e67814f909af722d8e7226f2cbb1a92c7684ef7 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 18:01:33 +0100 Subject: [PATCH 09/32] Rename to archtest --- pkg/{archtests => archtest}/acceptance_tests_arch_check_test.go | 2 +- pkg/{archtests => archtest}/assertions.go | 2 +- pkg/{archtests => archtest}/directory.go | 2 +- pkg/{archtests => archtest}/file.go | 2 +- pkg/{archtests => archtest}/file_filter_providers.go | 2 +- pkg/{archtests => archtest}/files.go | 2 +- pkg/{archtests => archtest}/method.go | 2 +- pkg/{archtests => archtest}/methods.go | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) rename pkg/{archtests => archtest}/acceptance_tests_arch_check_test.go (99%) rename pkg/{archtests => archtest}/assertions.go (98%) rename pkg/{archtests => archtest}/directory.go (97%) rename pkg/{archtests => archtest}/file.go (98%) rename pkg/{archtests => archtest}/file_filter_providers.go (97%) rename pkg/{archtests => archtest}/files.go (95%) rename pkg/{archtests => archtest}/method.go (86%) rename pkg/{archtests => archtest}/methods.go (90%) diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtest/acceptance_tests_arch_check_test.go similarity index 99% rename from pkg/archtests/acceptance_tests_arch_check_test.go rename to pkg/archtest/acceptance_tests_arch_check_test.go index 58ceb97480..cc573a223f 100644 --- a/pkg/archtests/acceptance_tests_arch_check_test.go +++ b/pkg/archtest/acceptance_tests_arch_check_test.go @@ -1,4 +1,4 @@ -package archtests +package archtest import ( "testing" diff --git a/pkg/archtests/assertions.go b/pkg/archtest/assertions.go similarity index 98% rename from pkg/archtests/assertions.go rename to pkg/archtest/assertions.go index 132ec605df..b8720f049d 100644 --- a/pkg/archtests/assertions.go +++ b/pkg/archtest/assertions.go @@ -1,4 +1,4 @@ -package archtests +package archtest import ( "regexp" diff --git a/pkg/archtests/directory.go b/pkg/archtest/directory.go similarity index 97% rename from pkg/archtests/directory.go rename to pkg/archtest/directory.go index ef7e769a6d..496ff82790 100644 --- a/pkg/archtests/directory.go +++ b/pkg/archtest/directory.go @@ -1,4 +1,4 @@ -package archtests +package archtest import ( "go/parser" diff --git a/pkg/archtests/file.go b/pkg/archtest/file.go similarity index 98% rename from pkg/archtests/file.go rename to pkg/archtest/file.go index 70d5d7fa35..c2f901562f 100644 --- a/pkg/archtests/file.go +++ b/pkg/archtest/file.go @@ -1,4 +1,4 @@ -package archtests +package archtest import ( "go/ast" diff --git a/pkg/archtests/file_filter_providers.go b/pkg/archtest/file_filter_providers.go similarity index 97% rename from pkg/archtests/file_filter_providers.go rename to pkg/archtest/file_filter_providers.go index 3ff85dcadc..f7601aafd3 100644 --- a/pkg/archtests/file_filter_providers.go +++ b/pkg/archtest/file_filter_providers.go @@ -1,4 +1,4 @@ -package archtests +package archtest import "regexp" diff --git a/pkg/archtests/files.go b/pkg/archtest/files.go similarity index 95% rename from pkg/archtests/files.go rename to pkg/archtest/files.go index 841097dd3c..06eba73f13 100644 --- a/pkg/archtests/files.go +++ b/pkg/archtest/files.go @@ -1,4 +1,4 @@ -package archtests +package archtest type FileFilter = func(*File) bool type FileReceiver = func(*File) diff --git a/pkg/archtests/method.go b/pkg/archtest/method.go similarity index 86% rename from pkg/archtests/method.go rename to pkg/archtest/method.go index 1d98d59a02..af62e043f7 100644 --- a/pkg/archtests/method.go +++ b/pkg/archtest/method.go @@ -1,4 +1,4 @@ -package archtests +package archtest type Method struct { name string diff --git a/pkg/archtests/methods.go b/pkg/archtest/methods.go similarity index 90% rename from pkg/archtests/methods.go rename to pkg/archtest/methods.go index adbb3f158f..558838aaac 100644 --- a/pkg/archtests/methods.go +++ b/pkg/archtest/methods.go @@ -1,4 +1,4 @@ -package archtests +package archtest type MethodReceiver = func(method *Method) From 8d6d8c870ca4326d0f1902e0e268d5f9db9e882f Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 18:06:49 +0100 Subject: [PATCH 10/32] Split lib and our usage into 2 different packages --- .../acceptance_tests_arch_check_test.go | 53 ------------------ pkg/archtest/assertions.go | 10 ++-- pkg/archtest/directory.go | 2 +- pkg/archtest/file.go | 18 +++---- pkg/archtest/file_filter_providers.go | 6 +-- pkg/archtest/files.go | 4 +- pkg/archtest/methods.go | 2 +- .../acceptance_tests_arch_check_test.go | 54 +++++++++++++++++++ 8 files changed, 75 insertions(+), 74 deletions(-) delete mode 100644 pkg/archtest/acceptance_tests_arch_check_test.go create mode 100644 pkg/archtests/acceptance_tests_arch_check_test.go diff --git a/pkg/archtest/acceptance_tests_arch_check_test.go b/pkg/archtest/acceptance_tests_arch_check_test.go deleted file mode 100644 index cc573a223f..0000000000 --- a/pkg/archtest/acceptance_tests_arch_check_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package archtest - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { - resourcesDirectory := NewDirectory("../resources/") - resourcesFiles, err := resourcesDirectory.allFiles() - require.NoError(t, err) - - t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - - iterateFiles(acceptanceTestFiles, func(file *File) { - assertPackage(t, file, "resources_test") - }) - }) - - t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := filterFiles(resourcesFiles, fileNameFilterProvider(acceptanceTestFileRegex)) - - iterateFiles(acceptanceTestFiles, func(file *File) { - iterateMethods(file.allExportedMethods(), func(method *Method) { - assertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) - - t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := filterFiles(resourcesFiles, fileNameFilterWithExclusionsProvider(testFileRegex, acceptanceTestFileRegex)) - - iterateFiles(otherTestFiles, func(file *File) { - iterateMethods(file.allExportedMethods(), func(method *Method) { - assertMethodNameDoesNotMatch(t, file, method, acceptanceTestNameRegex) - assertMethodNameMatches(t, file, method, testNameRegex) - }) - }) - }) - - t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { - t.Skipf("Currently there are non-acceptance tests in resources_test package") - packageFiles := filterFiles(resourcesFiles, packageFilterProvider("resources_test")) - - iterateFiles(packageFiles, func(file *File) { - iterateMethods(file.allExportedMethods(), func(method *Method) { - assertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) -} diff --git a/pkg/archtest/assertions.go b/pkg/archtest/assertions.go index b8720f049d..7f81f7048b 100644 --- a/pkg/archtest/assertions.go +++ b/pkg/archtest/assertions.go @@ -7,18 +7,18 @@ import ( "github.com/stretchr/testify/assert" ) -func assertPackage(t *testing.T, f *File, expectedPackage string) { +func AssertPackage(t *testing.T, f *File, expectedPackage string) { assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) } -func assertAcceptanceTestNamedCorrectly(t *testing.T, f *File, method *Method) { - assertMethodNameMatches(t, f, method, acceptanceTestNameRegex) +func AssertAcceptanceTestNamedCorrectly(t *testing.T, f *File, method *Method) { + AssertMethodNameMatches(t, f, method, AcceptanceTestNameRegex) } -func assertMethodNameMatches(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { +func AssertMethodNameMatches(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", f.fileName, method.name, regex.String()) } -func assertMethodNameDoesNotMatch(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { +func AssertMethodNameDoesNotMatch(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", f.fileName, method.name, regex.String()) } diff --git a/pkg/archtest/directory.go b/pkg/archtest/directory.go index 496ff82790..28c335057c 100644 --- a/pkg/archtest/directory.go +++ b/pkg/archtest/directory.go @@ -14,7 +14,7 @@ func NewDirectory(path string) *Directory { return &Directory{path: path} } -func (d *Directory) allFiles() ([]File, error) { +func (d *Directory) AllFiles() ([]File, error) { return d.files(nil) } diff --git a/pkg/archtest/file.go b/pkg/archtest/file.go index c2f901562f..67fd9d4960 100644 --- a/pkg/archtest/file.go +++ b/pkg/archtest/file.go @@ -6,27 +6,27 @@ import ( ) var ( - acceptanceTestFileRegex *regexp.Regexp - acceptanceTestNameRegex *regexp.Regexp - testFileRegex *regexp.Regexp - testNameRegex *regexp.Regexp + AcceptanceTestFileRegex *regexp.Regexp + AcceptanceTestNameRegex *regexp.Regexp + TestFileRegex *regexp.Regexp + TestNameRegex *regexp.Regexp ) func init() { var err error - acceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") + AcceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") if err != nil { panic(err) } - acceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") + AcceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") if err != nil { panic(err) } - testFileRegex, err = regexp.Compile("^.*_test.go$") + TestFileRegex, err = regexp.Compile("^.*_test.go$") if err != nil { panic(err) } - testNameRegex, err = regexp.Compile("^Test.*$") + TestNameRegex, err = regexp.Compile("^Test.*$") if err != nil { panic(err) } @@ -46,7 +46,7 @@ func NewFile(packageName string, fileName string, fileSrc *ast.File) *File { } } -func (f *File) allExportedMethods() []Method { +func (f *File) AllExportedMethods() []Method { allExportedMethods := make([]Method, 0) for _, d := range f.fileSrc.Decls { switch d.(type) { diff --git a/pkg/archtest/file_filter_providers.go b/pkg/archtest/file_filter_providers.go index f7601aafd3..fa51b3cc32 100644 --- a/pkg/archtest/file_filter_providers.go +++ b/pkg/archtest/file_filter_providers.go @@ -2,13 +2,13 @@ package archtest import "regexp" -func fileNameFilterProvider(regex *regexp.Regexp) FileFilter { +func FileNameFilterProvider(regex *regexp.Regexp) FileFilter { return func(f *File) bool { return regex.Match([]byte(f.fileName)) } } -func fileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) FileFilter { +func FileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex ...*regexp.Regexp) FileFilter { return func(f *File) bool { matches := regex.MatchString(f.fileName) for _, e := range exclusionRegex { @@ -18,7 +18,7 @@ func fileNameFilterWithExclusionsProvider(regex *regexp.Regexp, exclusionRegex . } } -func packageFilterProvider(packageName string) FileFilter { +func PackageFilterProvider(packageName string) FileFilter { return func(f *File) bool { return f.packageName == packageName } diff --git a/pkg/archtest/files.go b/pkg/archtest/files.go index 06eba73f13..0887e0d085 100644 --- a/pkg/archtest/files.go +++ b/pkg/archtest/files.go @@ -3,7 +3,7 @@ package archtest type FileFilter = func(*File) bool type FileReceiver = func(*File) -func filterFiles(files []File, filter FileFilter) []File { +func FilterFiles(files []File, filter FileFilter) []File { filteredFiles := make([]File, 0) for _, f := range files { if filter(&f) { @@ -13,7 +13,7 @@ func filterFiles(files []File, filter FileFilter) []File { return filteredFiles } -func iterateFiles(files []File, receiver FileReceiver) { +func IterateFiles(files []File, receiver FileReceiver) { for _, file := range files { receiver(&file) } diff --git a/pkg/archtest/methods.go b/pkg/archtest/methods.go index 558838aaac..99afd9207a 100644 --- a/pkg/archtest/methods.go +++ b/pkg/archtest/methods.go @@ -2,7 +2,7 @@ package archtest type MethodReceiver = func(method *Method) -func iterateMethods(methods []Method, receiver MethodReceiver) { +func IterateMethods(methods []Method, receiver MethodReceiver) { for _, method := range methods { receiver(&method) } diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/acceptance_tests_arch_check_test.go new file mode 100644 index 0000000000..03be3f99c3 --- /dev/null +++ b/pkg/archtests/acceptance_tests_arch_check_test.go @@ -0,0 +1,54 @@ +package archtests + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" + "github.com/stretchr/testify/require" +) + +func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { + resourcesDirectory := archtest.NewDirectory("../resources/") + resourcesFiles, err := resourcesDirectory.AllFiles() + require.NoError(t, err) + + t.Run("acceptance tests files have the right package", func(t *testing.T) { + acceptanceTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + archtest.AssertPackage(t, file, "resources_test") + }) + }) + + t.Run("acceptance tests are named correctly", func(t *testing.T) { + acceptanceTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) + + t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(otherTestFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) + archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) + }) + }) + }) + + t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { + t.Skipf("Currently there are non-acceptance tests in resources_test package") + packageFiles := archtest.FilterFiles(resourcesFiles, archtest.PackageFilterProvider("resources_test")) + + archtest.IterateFiles(packageFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) +} From 8cf98a40aa41a11d3350cc814876824034963fe2 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 18:10:16 +0100 Subject: [PATCH 11/32] Introduce datasources tests --- .../datasources_acceptance_tests_arch_test.go | 53 +++++++++++++++++++ ...> resources_acceptance_tests_arch_test.go} | 0 2 files changed, 53 insertions(+) create mode 100644 pkg/archtests/datasources_acceptance_tests_arch_test.go rename pkg/archtests/{acceptance_tests_arch_check_test.go => resources_acceptance_tests_arch_test.go} (100%) diff --git a/pkg/archtests/datasources_acceptance_tests_arch_test.go b/pkg/archtests/datasources_acceptance_tests_arch_test.go new file mode 100644 index 0000000000..30febc6fa6 --- /dev/null +++ b/pkg/archtests/datasources_acceptance_tests_arch_test.go @@ -0,0 +1,53 @@ +package archtests + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" + "github.com/stretchr/testify/require" +) + +func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { + datasourcesDirectory := archtest.NewDirectory("../datasources/") + datasourcesFiles, err := datasourcesDirectory.AllFiles() + require.NoError(t, err) + + t.Run("acceptance tests files have the right package", func(t *testing.T) { + acceptanceTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + archtest.AssertPackage(t, file, "datasources_test") + }) + }) + + t.Run("acceptance tests are named correctly", func(t *testing.T) { + acceptanceTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) + + t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) + + archtest.IterateFiles(otherTestFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) + archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) + }) + }) + }) + + t.Run("there are only acceptance tests in package datasources_test", func(t *testing.T) { + packageFiles := archtest.FilterFiles(datasourcesFiles, archtest.PackageFilterProvider("datasources_test")) + + archtest.IterateFiles(packageFiles, func(file *archtest.File) { + archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { + archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) +} diff --git a/pkg/archtests/acceptance_tests_arch_check_test.go b/pkg/archtests/resources_acceptance_tests_arch_test.go similarity index 100% rename from pkg/archtests/acceptance_tests_arch_check_test.go rename to pkg/archtests/resources_acceptance_tests_arch_test.go From ed3b744c8884c4a07504027db1179da80879561e Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 18:31:29 +0100 Subject: [PATCH 12/32] Start testing archtest --- pkg/archtest/archtest_test.go | 38 +++++++++++++++++++++++++++ pkg/archtest/file.go | 8 ++++++ pkg/archtest/testdata/dir1/sample1.go | 1 + pkg/archtest/testdata/dir1/sample2.go | 1 + 4 files changed, 48 insertions(+) create mode 100644 pkg/archtest/archtest_test.go create mode 100644 pkg/archtest/testdata/dir1/sample1.go create mode 100644 pkg/archtest/testdata/dir1/sample2.go diff --git a/pkg/archtest/archtest_test.go b/pkg/archtest/archtest_test.go new file mode 100644 index 0000000000..0da4e5913a --- /dev/null +++ b/pkg/archtest/archtest_test.go @@ -0,0 +1,38 @@ +package archtest_test + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_Directory(t *testing.T) { + // TODO: parametrize test + t.Run("list all files in the given directory", func(t *testing.T) { + dir := archtest.NewDirectory("testdata/dir1") + + allFiles, err := dir.AllFiles() + require.NoError(t, err) + + assert.Len(t, allFiles, 2) + + fileNames := make([]string, 0, len(allFiles)) + for _, f := range allFiles { + fileNames = append(fileNames, f.FileName()) + } + expectedFileNames := []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"} + assert.ElementsMatch(t, fileNames, expectedFileNames) + + packageNames := make(map[string]bool) + for _, f := range allFiles { + packageNames[f.PackageName()] = true + } + assert.Len(t, packageNames, 1) + expectedPackageNames := []string{"dir1"} + for _, name := range expectedPackageNames { + assert.Contains(t, packageNames, name) + } + }) +} diff --git a/pkg/archtest/file.go b/pkg/archtest/file.go index 67fd9d4960..b37a43c767 100644 --- a/pkg/archtest/file.go +++ b/pkg/archtest/file.go @@ -46,6 +46,14 @@ func NewFile(packageName string, fileName string, fileSrc *ast.File) *File { } } +func (f *File) PackageName() string { + return f.packageName +} + +func (f *File) FileName() string { + return f.fileName +} + func (f *File) AllExportedMethods() []Method { allExportedMethods := make([]Method, 0) for _, d := range f.fileSrc.Decls { diff --git a/pkg/archtest/testdata/dir1/sample1.go b/pkg/archtest/testdata/dir1/sample1.go new file mode 100644 index 0000000000..b719eadc09 --- /dev/null +++ b/pkg/archtest/testdata/dir1/sample1.go @@ -0,0 +1 @@ +package dir1 diff --git a/pkg/archtest/testdata/dir1/sample2.go b/pkg/archtest/testdata/dir1/sample2.go new file mode 100644 index 0000000000..b719eadc09 --- /dev/null +++ b/pkg/archtest/testdata/dir1/sample2.go @@ -0,0 +1 @@ +package dir1 From 55f5d5682629221d8b760730817d4f0c0bba2a05 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Wed, 22 Nov 2023 18:44:36 +0100 Subject: [PATCH 13/32] Parametrize directories test --- pkg/archtest/archtest_test.go | 53 +++++++++++-------- pkg/archtest/testdata/dir2/sample1.go | 1 + pkg/archtest/testdata/dir2/sample1_test.go | 1 + pkg/archtest/testdata/dir3/sample1.go | 1 + .../testdata/dir3/sample1_acceptance_test.go | 1 + 5 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 pkg/archtest/testdata/dir2/sample1.go create mode 100644 pkg/archtest/testdata/dir2/sample1_test.go create mode 100644 pkg/archtest/testdata/dir3/sample1.go create mode 100644 pkg/archtest/testdata/dir3/sample1_acceptance_test.go diff --git a/pkg/archtest/archtest_test.go b/pkg/archtest/archtest_test.go index 0da4e5913a..56516fae42 100644 --- a/pkg/archtest/archtest_test.go +++ b/pkg/archtest/archtest_test.go @@ -8,31 +8,40 @@ import ( "github.com/stretchr/testify/require" ) +// TODO: create jira issue in tests stabilization (+one-pager?) func Test_Directory(t *testing.T) { - // TODO: parametrize test - t.Run("list all files in the given directory", func(t *testing.T) { - dir := archtest.NewDirectory("testdata/dir1") + tests := []struct { + directory string + expectedFileNames []string + expectedPackageNames []string + }{ + {directory: "testdata/dir1", expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"}, expectedPackageNames: []string{"dir1"}}, + {directory: "testdata/dir2", expectedFileNames: []string{"testdata/dir2/sample1.go", "testdata/dir2/sample1_test.go"}, expectedPackageNames: []string{"dir2", "dir2_test"}}, + {directory: "testdata/dir3", expectedFileNames: []string{"testdata/dir3/sample1.go", "testdata/dir3/sample1_acceptance_test.go"}, expectedPackageNames: []string{"dir3", "dir3_test"}}, + } + for _, tt := range tests { + t.Run("list all files in the given directory", func(t *testing.T) { + dir := archtest.NewDirectory(tt.directory) - allFiles, err := dir.AllFiles() - require.NoError(t, err) + allFiles, err := dir.AllFiles() + require.NoError(t, err) - assert.Len(t, allFiles, 2) + assert.Len(t, allFiles, len(tt.expectedFileNames)) - fileNames := make([]string, 0, len(allFiles)) - for _, f := range allFiles { - fileNames = append(fileNames, f.FileName()) - } - expectedFileNames := []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"} - assert.ElementsMatch(t, fileNames, expectedFileNames) + fileNames := make([]string, 0, len(allFiles)) + for _, f := range allFiles { + fileNames = append(fileNames, f.FileName()) + } + assert.ElementsMatch(t, fileNames, tt.expectedFileNames) - packageNames := make(map[string]bool) - for _, f := range allFiles { - packageNames[f.PackageName()] = true - } - assert.Len(t, packageNames, 1) - expectedPackageNames := []string{"dir1"} - for _, name := range expectedPackageNames { - assert.Contains(t, packageNames, name) - } - }) + packageNames := make(map[string]bool) + for _, f := range allFiles { + packageNames[f.PackageName()] = true + } + assert.Len(t, packageNames, len(tt.expectedPackageNames)) + for _, name := range tt.expectedPackageNames { + assert.Contains(t, packageNames, name) + } + }) + } } diff --git a/pkg/archtest/testdata/dir2/sample1.go b/pkg/archtest/testdata/dir2/sample1.go new file mode 100644 index 0000000000..6fe35e9e59 --- /dev/null +++ b/pkg/archtest/testdata/dir2/sample1.go @@ -0,0 +1 @@ +package dir2 diff --git a/pkg/archtest/testdata/dir2/sample1_test.go b/pkg/archtest/testdata/dir2/sample1_test.go new file mode 100644 index 0000000000..3a1d6c990c --- /dev/null +++ b/pkg/archtest/testdata/dir2/sample1_test.go @@ -0,0 +1 @@ +package dir2_test diff --git a/pkg/archtest/testdata/dir3/sample1.go b/pkg/archtest/testdata/dir3/sample1.go new file mode 100644 index 0000000000..6ea203550b --- /dev/null +++ b/pkg/archtest/testdata/dir3/sample1.go @@ -0,0 +1 @@ +package dir3 diff --git a/pkg/archtest/testdata/dir3/sample1_acceptance_test.go b/pkg/archtest/testdata/dir3/sample1_acceptance_test.go new file mode 100644 index 0000000000..d3ddb6dea6 --- /dev/null +++ b/pkg/archtest/testdata/dir3/sample1_acceptance_test.go @@ -0,0 +1 @@ +package dir3_test From ca9a89bda88622f3ed28e34e15449770f16e584c Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 18:43:46 +0100 Subject: [PATCH 14/32] Change API --- pkg/archtest/archtest_test.go | 5 +---- pkg/archtest/directory.go | 10 +++++----- pkg/archtest/files.go | 5 +++-- .../datasources_acceptance_tests_arch_test.go | 20 +++++++++---------- .../resources_acceptance_tests_arch_test.go | 20 +++++++++---------- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/pkg/archtest/archtest_test.go b/pkg/archtest/archtest_test.go index 56516fae42..ab557aad6f 100644 --- a/pkg/archtest/archtest_test.go +++ b/pkg/archtest/archtest_test.go @@ -5,7 +5,6 @@ import ( "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // TODO: create jira issue in tests stabilization (+one-pager?) @@ -23,9 +22,7 @@ func Test_Directory(t *testing.T) { t.Run("list all files in the given directory", func(t *testing.T) { dir := archtest.NewDirectory(tt.directory) - allFiles, err := dir.AllFiles() - require.NoError(t, err) - + allFiles := dir.AllFiles() assert.Len(t, allFiles, len(tt.expectedFileNames)) fileNames := make([]string, 0, len(allFiles)) diff --git a/pkg/archtest/directory.go b/pkg/archtest/directory.go index 28c335057c..d0b714eee0 100644 --- a/pkg/archtest/directory.go +++ b/pkg/archtest/directory.go @@ -14,20 +14,20 @@ func NewDirectory(path string) *Directory { return &Directory{path: path} } -func (d *Directory) AllFiles() ([]File, error) { +func (d *Directory) AllFiles() Files { return d.files(nil) } -func (d *Directory) files(filter func(fi fs.FileInfo) bool) ([]File, error) { +func (d *Directory) files(filter func(fi fs.FileInfo) bool) Files { packagesDict, err := parser.ParseDir(token.NewFileSet(), d.path, filter, 0) if err != nil { - return nil, err + panic(err) } - files := make([]File, 0) + files := make(Files, 0) for packageName, astPackage := range packagesDict { for fileName, fileSrc := range astPackage.Files { files = append(files, *NewFile(packageName, fileName, fileSrc)) } } - return files, nil + return files } diff --git a/pkg/archtest/files.go b/pkg/archtest/files.go index 0887e0d085..6e75669c1e 100644 --- a/pkg/archtest/files.go +++ b/pkg/archtest/files.go @@ -2,8 +2,9 @@ package archtest type FileFilter = func(*File) bool type FileReceiver = func(*File) +type Files []File -func FilterFiles(files []File, filter FileFilter) []File { +func (files Files) Filter(filter FileFilter) Files { filteredFiles := make([]File, 0) for _, f := range files { if filter(&f) { @@ -13,7 +14,7 @@ func FilterFiles(files []File, filter FileFilter) []File { return filteredFiles } -func IterateFiles(files []File, receiver FileReceiver) { +func (files Files) All(receiver FileReceiver) { for _, file := range files { receiver(&file) } diff --git a/pkg/archtests/datasources_acceptance_tests_arch_test.go b/pkg/archtests/datasources_acceptance_tests_arch_test.go index 30febc6fa6..cd7bb774ec 100644 --- a/pkg/archtests/datasources_acceptance_tests_arch_test.go +++ b/pkg/archtests/datasources_acceptance_tests_arch_test.go @@ -4,26 +4,24 @@ import ( "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" - "github.com/stretchr/testify/require" ) func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { datasourcesDirectory := archtest.NewDirectory("../datasources/") - datasourcesFiles, err := datasourcesDirectory.AllFiles() - require.NoError(t, err) + datasourcesFiles := datasourcesDirectory.AllFiles() t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + acceptanceTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + acceptanceTestFiles.All(func(file *archtest.File) { archtest.AssertPackage(t, file, "datasources_test") }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + acceptanceTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + acceptanceTestFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) }) @@ -31,9 +29,9 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { }) t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := archtest.FilterFiles(datasourcesFiles, archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) + otherTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(otherTestFiles, func(file *archtest.File) { + otherTestFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) @@ -42,9 +40,9 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { }) t.Run("there are only acceptance tests in package datasources_test", func(t *testing.T) { - packageFiles := archtest.FilterFiles(datasourcesFiles, archtest.PackageFilterProvider("datasources_test")) + packageFiles := datasourcesFiles.Filter(archtest.PackageFilterProvider("datasources_test")) - archtest.IterateFiles(packageFiles, func(file *archtest.File) { + packageFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) }) diff --git a/pkg/archtests/resources_acceptance_tests_arch_test.go b/pkg/archtests/resources_acceptance_tests_arch_test.go index 03be3f99c3..8d3e108876 100644 --- a/pkg/archtests/resources_acceptance_tests_arch_test.go +++ b/pkg/archtests/resources_acceptance_tests_arch_test.go @@ -4,26 +4,24 @@ import ( "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" - "github.com/stretchr/testify/require" ) func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { resourcesDirectory := archtest.NewDirectory("../resources/") - resourcesFiles, err := resourcesDirectory.AllFiles() - require.NoError(t, err) + resourcesFiles := resourcesDirectory.AllFiles() t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + acceptanceTestFiles := resourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + acceptanceTestFiles.All(func(file *archtest.File) { archtest.AssertPackage(t, file, "resources_test") }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) + acceptanceTestFiles := resourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(acceptanceTestFiles, func(file *archtest.File) { + acceptanceTestFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) }) @@ -31,9 +29,9 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { }) t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := archtest.FilterFiles(resourcesFiles, archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) + otherTestFiles := resourcesFiles.Filter(archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) - archtest.IterateFiles(otherTestFiles, func(file *archtest.File) { + otherTestFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) @@ -43,9 +41,9 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { t.Skipf("Currently there are non-acceptance tests in resources_test package") - packageFiles := archtest.FilterFiles(resourcesFiles, archtest.PackageFilterProvider("resources_test")) + packageFiles := resourcesFiles.Filter(archtest.PackageFilterProvider("resources_test")) - archtest.IterateFiles(packageFiles, func(file *archtest.File) { + packageFiles.All(func(file *archtest.File) { archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) }) From b3610ccef44090568947df606e83b891a21c7169 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 18:49:42 +0100 Subject: [PATCH 15/32] Rename to architest --- .../architest_test.go} | 6 +-- pkg/{archtest => architest}/assertions.go | 2 +- pkg/{archtest => architest}/directory.go | 2 +- pkg/{archtest => architest}/file.go | 6 +-- .../file_filter_providers.go | 2 +- pkg/{archtest => architest}/files.go | 2 +- pkg/{archtest => architest}/method.go | 2 +- pkg/{archtest => architest}/methods.go | 5 +- .../testdata/dir1/sample1.go | 0 .../testdata/dir1/sample2.go | 0 .../testdata/dir2/sample1.go | 0 .../testdata/dir2/sample1_test.go | 0 .../testdata/dir3/sample1.go | 0 .../testdata/dir3/sample1_acceptance_test.go | 0 .../datasources_acceptance_tests_arch_test.go | 51 ++++++++++++++++++ .../resources_acceptance_tests_arch_test.go | 52 +++++++++++++++++++ .../datasources_acceptance_tests_arch_test.go | 51 ------------------ .../resources_acceptance_tests_arch_test.go | 52 ------------------- 18 files changed, 117 insertions(+), 116 deletions(-) rename pkg/{archtest/archtest_test.go => architest/architest_test.go} (95%) rename pkg/{archtest => architest}/assertions.go (98%) rename pkg/{archtest => architest}/directory.go (97%) rename pkg/{archtest => architest}/file.go (92%) rename pkg/{archtest => architest}/file_filter_providers.go (97%) rename pkg/{archtest => architest}/files.go (95%) rename pkg/{archtest => architest}/method.go (86%) rename pkg/{archtest => architest}/methods.go (52%) rename pkg/{archtest => architest}/testdata/dir1/sample1.go (100%) rename pkg/{archtest => architest}/testdata/dir1/sample2.go (100%) rename pkg/{archtest => architest}/testdata/dir2/sample1.go (100%) rename pkg/{archtest => architest}/testdata/dir2/sample1_test.go (100%) rename pkg/{archtest => architest}/testdata/dir3/sample1.go (100%) rename pkg/{archtest => architest}/testdata/dir3/sample1_acceptance_test.go (100%) create mode 100644 pkg/architests/datasources_acceptance_tests_arch_test.go create mode 100644 pkg/architests/resources_acceptance_tests_arch_test.go delete mode 100644 pkg/archtests/datasources_acceptance_tests_arch_test.go delete mode 100644 pkg/archtests/resources_acceptance_tests_arch_test.go diff --git a/pkg/archtest/archtest_test.go b/pkg/architest/architest_test.go similarity index 95% rename from pkg/archtest/archtest_test.go rename to pkg/architest/architest_test.go index ab557aad6f..2a77b1f206 100644 --- a/pkg/archtest/archtest_test.go +++ b/pkg/architest/architest_test.go @@ -1,9 +1,9 @@ -package archtest_test +package architest_test import ( "testing" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" "github.com/stretchr/testify/assert" ) @@ -20,7 +20,7 @@ func Test_Directory(t *testing.T) { } for _, tt := range tests { t.Run("list all files in the given directory", func(t *testing.T) { - dir := archtest.NewDirectory(tt.directory) + dir := architest.NewDirectory(tt.directory) allFiles := dir.AllFiles() assert.Len(t, allFiles, len(tt.expectedFileNames)) diff --git a/pkg/archtest/assertions.go b/pkg/architest/assertions.go similarity index 98% rename from pkg/archtest/assertions.go rename to pkg/architest/assertions.go index 7f81f7048b..c35c6deee9 100644 --- a/pkg/archtest/assertions.go +++ b/pkg/architest/assertions.go @@ -1,4 +1,4 @@ -package archtest +package architest import ( "regexp" diff --git a/pkg/archtest/directory.go b/pkg/architest/directory.go similarity index 97% rename from pkg/archtest/directory.go rename to pkg/architest/directory.go index d0b714eee0..1036fb08a5 100644 --- a/pkg/archtest/directory.go +++ b/pkg/architest/directory.go @@ -1,4 +1,4 @@ -package archtest +package architest import ( "go/parser" diff --git a/pkg/archtest/file.go b/pkg/architest/file.go similarity index 92% rename from pkg/archtest/file.go rename to pkg/architest/file.go index b37a43c767..07b525227f 100644 --- a/pkg/archtest/file.go +++ b/pkg/architest/file.go @@ -1,4 +1,4 @@ -package archtest +package architest import ( "go/ast" @@ -54,8 +54,8 @@ func (f *File) FileName() string { return f.fileName } -func (f *File) AllExportedMethods() []Method { - allExportedMethods := make([]Method, 0) +func (f *File) AllExportedMethods() Methods { + allExportedMethods := make(Methods, 0) for _, d := range f.fileSrc.Decls { switch d.(type) { case *ast.FuncDecl: diff --git a/pkg/archtest/file_filter_providers.go b/pkg/architest/file_filter_providers.go similarity index 97% rename from pkg/archtest/file_filter_providers.go rename to pkg/architest/file_filter_providers.go index fa51b3cc32..bb2279488d 100644 --- a/pkg/archtest/file_filter_providers.go +++ b/pkg/architest/file_filter_providers.go @@ -1,4 +1,4 @@ -package archtest +package architest import "regexp" diff --git a/pkg/archtest/files.go b/pkg/architest/files.go similarity index 95% rename from pkg/archtest/files.go rename to pkg/architest/files.go index 6e75669c1e..4462d01485 100644 --- a/pkg/archtest/files.go +++ b/pkg/architest/files.go @@ -1,4 +1,4 @@ -package archtest +package architest type FileFilter = func(*File) bool type FileReceiver = func(*File) diff --git a/pkg/archtest/method.go b/pkg/architest/method.go similarity index 86% rename from pkg/archtest/method.go rename to pkg/architest/method.go index af62e043f7..8678346628 100644 --- a/pkg/archtest/method.go +++ b/pkg/architest/method.go @@ -1,4 +1,4 @@ -package archtest +package architest type Method struct { name string diff --git a/pkg/archtest/methods.go b/pkg/architest/methods.go similarity index 52% rename from pkg/archtest/methods.go rename to pkg/architest/methods.go index 99afd9207a..e737ae1d5b 100644 --- a/pkg/archtest/methods.go +++ b/pkg/architest/methods.go @@ -1,8 +1,9 @@ -package archtest +package architest type MethodReceiver = func(method *Method) +type Methods []Method -func IterateMethods(methods []Method, receiver MethodReceiver) { +func (methods Methods) All(receiver MethodReceiver) { for _, method := range methods { receiver(&method) } diff --git a/pkg/archtest/testdata/dir1/sample1.go b/pkg/architest/testdata/dir1/sample1.go similarity index 100% rename from pkg/archtest/testdata/dir1/sample1.go rename to pkg/architest/testdata/dir1/sample1.go diff --git a/pkg/archtest/testdata/dir1/sample2.go b/pkg/architest/testdata/dir1/sample2.go similarity index 100% rename from pkg/archtest/testdata/dir1/sample2.go rename to pkg/architest/testdata/dir1/sample2.go diff --git a/pkg/archtest/testdata/dir2/sample1.go b/pkg/architest/testdata/dir2/sample1.go similarity index 100% rename from pkg/archtest/testdata/dir2/sample1.go rename to pkg/architest/testdata/dir2/sample1.go diff --git a/pkg/archtest/testdata/dir2/sample1_test.go b/pkg/architest/testdata/dir2/sample1_test.go similarity index 100% rename from pkg/archtest/testdata/dir2/sample1_test.go rename to pkg/architest/testdata/dir2/sample1_test.go diff --git a/pkg/archtest/testdata/dir3/sample1.go b/pkg/architest/testdata/dir3/sample1.go similarity index 100% rename from pkg/archtest/testdata/dir3/sample1.go rename to pkg/architest/testdata/dir3/sample1.go diff --git a/pkg/archtest/testdata/dir3/sample1_acceptance_test.go b/pkg/architest/testdata/dir3/sample1_acceptance_test.go similarity index 100% rename from pkg/archtest/testdata/dir3/sample1_acceptance_test.go rename to pkg/architest/testdata/dir3/sample1_acceptance_test.go diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go new file mode 100644 index 0000000000..5d93bfa4af --- /dev/null +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -0,0 +1,51 @@ +package architests + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" +) + +func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { + datasourcesDirectory := architest.NewDirectory("../datasources/") + datasourcesFiles := datasourcesDirectory.AllFiles() + + t.Run("acceptance tests files have the right package", func(t *testing.T) { + acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + + acceptanceTestFiles.All(func(file *architest.File) { + architest.AssertPackage(t, file, "datasources_test") + }) + }) + + t.Run("acceptance tests are named correctly", func(t *testing.T) { + acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + + acceptanceTestFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) + + t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := datasourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex)) + + otherTestFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertMethodNameDoesNotMatch(t, file, method, architest.AcceptanceTestNameRegex) + architest.AssertMethodNameMatches(t, file, method, architest.TestNameRegex) + }) + }) + }) + + t.Run("there are only acceptance tests in package datasources_test", func(t *testing.T) { + packageFiles := datasourcesFiles.Filter(architest.PackageFilterProvider("datasources_test")) + + packageFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) +} diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go new file mode 100644 index 0000000000..be02a19cc2 --- /dev/null +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -0,0 +1,52 @@ +package architests + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" +) + +func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { + resourcesDirectory := architest.NewDirectory("../resources/") + resourcesFiles := resourcesDirectory.AllFiles() + + t.Run("acceptance tests files have the right package", func(t *testing.T) { + acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + + acceptanceTestFiles.All(func(file *architest.File) { + architest.AssertPackage(t, file, "resources_test") + }) + }) + + t.Run("acceptance tests are named correctly", func(t *testing.T) { + acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + + acceptanceTestFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) + + t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := resourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex)) + + otherTestFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertMethodNameDoesNotMatch(t, file, method, architest.AcceptanceTestNameRegex) + architest.AssertMethodNameMatches(t, file, method, architest.TestNameRegex) + }) + }) + }) + + t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { + t.Skipf("Currently there are non-acceptance tests in resources_test package") + packageFiles := resourcesFiles.Filter(architest.PackageFilterProvider("resources_test")) + + packageFiles.All(func(file *architest.File) { + file.AllExportedMethods().All(func(method *architest.Method) { + architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + }) + }) + }) +} diff --git a/pkg/archtests/datasources_acceptance_tests_arch_test.go b/pkg/archtests/datasources_acceptance_tests_arch_test.go deleted file mode 100644 index cd7bb774ec..0000000000 --- a/pkg/archtests/datasources_acceptance_tests_arch_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package archtests - -import ( - "testing" - - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" -) - -func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { - datasourcesDirectory := archtest.NewDirectory("../datasources/") - datasourcesFiles := datasourcesDirectory.AllFiles() - - t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - - acceptanceTestFiles.All(func(file *archtest.File) { - archtest.AssertPackage(t, file, "datasources_test") - }) - }) - - t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - - acceptanceTestFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) - - t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := datasourcesFiles.Filter(archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) - - otherTestFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) - archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) - }) - }) - }) - - t.Run("there are only acceptance tests in package datasources_test", func(t *testing.T) { - packageFiles := datasourcesFiles.Filter(archtest.PackageFilterProvider("datasources_test")) - - packageFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) -} diff --git a/pkg/archtests/resources_acceptance_tests_arch_test.go b/pkg/archtests/resources_acceptance_tests_arch_test.go deleted file mode 100644 index 8d3e108876..0000000000 --- a/pkg/archtests/resources_acceptance_tests_arch_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package archtests - -import ( - "testing" - - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/archtest" -) - -func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { - resourcesDirectory := archtest.NewDirectory("../resources/") - resourcesFiles := resourcesDirectory.AllFiles() - - t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - - acceptanceTestFiles.All(func(file *archtest.File) { - archtest.AssertPackage(t, file, "resources_test") - }) - }) - - t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(archtest.FileNameFilterProvider(archtest.AcceptanceTestFileRegex)) - - acceptanceTestFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) - - t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := resourcesFiles.Filter(archtest.FileNameFilterWithExclusionsProvider(archtest.TestFileRegex, archtest.AcceptanceTestFileRegex)) - - otherTestFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertMethodNameDoesNotMatch(t, file, method, archtest.AcceptanceTestNameRegex) - archtest.AssertMethodNameMatches(t, file, method, archtest.TestNameRegex) - }) - }) - }) - - t.Run("there are only acceptance tests in package resources_test", func(t *testing.T) { - t.Skipf("Currently there are non-acceptance tests in resources_test package") - packageFiles := resourcesFiles.Filter(archtest.PackageFilterProvider("resources_test")) - - packageFiles.All(func(file *archtest.File) { - archtest.IterateMethods(file.AllExportedMethods(), func(method *archtest.Method) { - archtest.AssertAcceptanceTestNamedCorrectly(t, file, method) - }) - }) - }) -} From 7c3ef6bd8dc8250c181e6d3f5974f3e8543ff887 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 18:55:39 +0100 Subject: [PATCH 16/32] Add nicer assertions --- pkg/architest/assertions.go | 10 +++++----- .../datasources_acceptance_tests_arch_test.go | 10 +++++----- pkg/architests/resources_acceptance_tests_arch_test.go | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index c35c6deee9..f7e66337ce 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -7,18 +7,18 @@ import ( "github.com/stretchr/testify/assert" ) -func AssertPackage(t *testing.T, f *File, expectedPackage string) { +func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) } -func AssertAcceptanceTestNamedCorrectly(t *testing.T, f *File, method *Method) { - AssertMethodNameMatches(t, f, method, AcceptanceTestNameRegex) +func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T, f *File) { + method.AssertNameMatches(t, f, AcceptanceTestNameRegex) } -func AssertMethodNameMatches(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { +func (method *Method) AssertNameMatches(t *testing.T, f *File, regex *regexp.Regexp) { assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", f.fileName, method.name, regex.String()) } -func AssertMethodNameDoesNotMatch(t *testing.T, f *File, method *Method, regex *regexp.Regexp) { +func (method *Method) AssertNameDoesNotMatch(t *testing.T, f *File, regex *regexp.Regexp) { assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", f.fileName, method.name, regex.String()) } diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index 5d93bfa4af..092437aec3 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -14,7 +14,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { - architest.AssertPackage(t, file, "datasources_test") + file.AssertHasPackage(t, "datasources_test") }) }) @@ -23,7 +23,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { acceptanceTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + method.AssertAcceptanceTestNamedCorrectly(t, file) }) }) }) @@ -33,8 +33,8 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertMethodNameDoesNotMatch(t, file, method, architest.AcceptanceTestNameRegex) - architest.AssertMethodNameMatches(t, file, method, architest.TestNameRegex) + method.AssertNameDoesNotMatch(t, file, architest.AcceptanceTestNameRegex) + method.AssertNameMatches(t, file, architest.TestNameRegex) }) }) }) @@ -44,7 +44,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { packageFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + method.AssertAcceptanceTestNamedCorrectly(t, file) }) }) }) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index be02a19cc2..dab96552d8 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -14,7 +14,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { - architest.AssertPackage(t, file, "resources_test") + file.AssertHasPackage(t, "resources_test") }) }) @@ -23,7 +23,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { acceptanceTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + method.AssertAcceptanceTestNamedCorrectly(t, file) }) }) }) @@ -33,8 +33,8 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertMethodNameDoesNotMatch(t, file, method, architest.AcceptanceTestNameRegex) - architest.AssertMethodNameMatches(t, file, method, architest.TestNameRegex) + method.AssertNameDoesNotMatch(t, file, architest.AcceptanceTestNameRegex) + method.AssertNameMatches(t, file, architest.TestNameRegex) }) }) }) @@ -45,7 +45,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { packageFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - architest.AssertAcceptanceTestNamedCorrectly(t, file, method) + method.AssertAcceptanceTestNamedCorrectly(t, file) }) }) }) From 7c7b504b7369e90a15b71106a39268c6a75a837a Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 18:58:18 +0100 Subject: [PATCH 17/32] Add file to method --- pkg/architest/assertions.go | 12 ++++++------ pkg/architest/file.go | 2 +- pkg/architest/method.go | 4 +++- .../datasources_acceptance_tests_arch_test.go | 8 ++++---- .../resources_acceptance_tests_arch_test.go | 8 ++++---- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index f7e66337ce..e104839f8d 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -11,14 +11,14 @@ func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) } -func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T, f *File) { - method.AssertNameMatches(t, f, AcceptanceTestNameRegex) +func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { + method.AssertNameMatches(t, AcceptanceTestNameRegex) } -func (method *Method) AssertNameMatches(t *testing.T, f *File, regex *regexp.Regexp) { - assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", f.fileName, method.name, regex.String()) +func (method *Method) AssertNameMatches(t *testing.T, regex *regexp.Regexp) { + assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", method.file.fileName, method.name, regex.String()) } -func (method *Method) AssertNameDoesNotMatch(t *testing.T, f *File, regex *regexp.Regexp) { - assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", f.fileName, method.name, regex.String()) +func (method *Method) AssertNameDoesNotMatch(t *testing.T, regex *regexp.Regexp) { + assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", method.file.fileName, method.name, regex.String()) } diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 07b525227f..ad567eeb5b 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -61,7 +61,7 @@ func (f *File) AllExportedMethods() Methods { case *ast.FuncDecl: name := d.(*ast.FuncDecl).Name.Name if ast.IsExported(name) { - allExportedMethods = append(allExportedMethods, *NewMethod(name)) + allExportedMethods = append(allExportedMethods, *NewMethod(name, f)) } } } diff --git a/pkg/architest/method.go b/pkg/architest/method.go index 8678346628..21360a2004 100644 --- a/pkg/architest/method.go +++ b/pkg/architest/method.go @@ -2,10 +2,12 @@ package architest type Method struct { name string + file *File } -func NewMethod(name string) *Method { +func NewMethod(name string, file *File) *Method { return &Method{ name: name, + file: file, } } diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index 092437aec3..d98d82f717 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -23,7 +23,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { acceptanceTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertAcceptanceTestNamedCorrectly(t, file) + method.AssertAcceptanceTestNamedCorrectly(t) }) }) }) @@ -33,8 +33,8 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertNameDoesNotMatch(t, file, architest.AcceptanceTestNameRegex) - method.AssertNameMatches(t, file, architest.TestNameRegex) + method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) + method.AssertNameMatches(t, architest.TestNameRegex) }) }) }) @@ -44,7 +44,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { packageFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertAcceptanceTestNamedCorrectly(t, file) + method.AssertAcceptanceTestNamedCorrectly(t) }) }) }) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index dab96552d8..1fd8ae0ced 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -23,7 +23,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { acceptanceTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertAcceptanceTestNamedCorrectly(t, file) + method.AssertAcceptanceTestNamedCorrectly(t) }) }) }) @@ -33,8 +33,8 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertNameDoesNotMatch(t, file, architest.AcceptanceTestNameRegex) - method.AssertNameMatches(t, file, architest.TestNameRegex) + method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) + method.AssertNameMatches(t, architest.TestNameRegex) }) }) }) @@ -45,7 +45,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { packageFiles.All(func(file *architest.File) { file.AllExportedMethods().All(func(method *architest.Method) { - method.AssertAcceptanceTestNamedCorrectly(t, file) + method.AssertAcceptanceTestNamedCorrectly(t) }) }) }) From 5ef0cf0e8af7173048fe6e467487d347a6aee9ec Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 18:59:15 +0100 Subject: [PATCH 18/32] Rename to exported methods --- pkg/architest/file.go | 2 +- pkg/architests/datasources_acceptance_tests_arch_test.go | 6 +++--- pkg/architests/resources_acceptance_tests_arch_test.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/architest/file.go b/pkg/architest/file.go index ad567eeb5b..e0d25020af 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -54,7 +54,7 @@ func (f *File) FileName() string { return f.fileName } -func (f *File) AllExportedMethods() Methods { +func (f *File) ExportedMethods() Methods { allExportedMethods := make(Methods, 0) for _, d := range f.fileSrc.Decls { switch d.(type) { diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index d98d82f717..baa13c39d6 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -22,7 +22,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) }) }) @@ -32,7 +32,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { otherTestFiles := datasourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex)) otherTestFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) method.AssertNameMatches(t, architest.TestNameRegex) }) @@ -43,7 +43,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { packageFiles := datasourcesFiles.Filter(architest.PackageFilterProvider("datasources_test")) packageFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) }) }) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 1fd8ae0ced..5efebb566d 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -22,7 +22,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) }) }) @@ -32,7 +32,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { otherTestFiles := resourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex)) otherTestFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) method.AssertNameMatches(t, architest.TestNameRegex) }) @@ -44,7 +44,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { packageFiles := resourcesFiles.Filter(architest.PackageFilterProvider("resources_test")) packageFiles.All(func(file *architest.File) { - file.AllExportedMethods().All(func(method *architest.Method) { + file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) }) }) From 94fc50b97deebbf6ed0ffa748c1e14b959fff7b8 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 19:15:44 +0100 Subject: [PATCH 19/32] Test file --- pkg/architest/architest_test.go | 24 ++++++++++++++++++++++++ pkg/architest/assertions.go | 6 +++--- pkg/architest/file.go | 11 +++++++++++ pkg/architest/method.go | 8 ++++++++ pkg/architest/testdata/dir1/sample2.go | 4 ++++ 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 2a77b1f206..6c1df6b87c 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -42,3 +42,27 @@ func Test_Directory(t *testing.T) { }) } } + +func Test_Files(t *testing.T) { + tests := []struct { + filePath string + expectedMethodNames []string + }{ + {filePath: "testdata/dir1/sample1.go", expectedMethodNames: []string{}}, + {filePath: "testdata/dir1/sample2.go", expectedMethodNames: []string{"A"}}, + } + for _, tt := range tests { + t.Run("list all methods in file", func(t *testing.T) { + file := architest.NewFileFromPath(tt.filePath) + + exportedMethods := file.ExportedMethods() + assert.Len(t, exportedMethods, len(tt.expectedMethodNames)) + + methodNames := make([]string, 0, len(exportedMethods)) + for _, m := range exportedMethods { + methodNames = append(methodNames, m.Name()) + } + assert.ElementsMatch(t, methodNames, tt.expectedMethodNames) + }) + } +} diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index e104839f8d..89cbec6843 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -8,7 +8,7 @@ import ( ) func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { - assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.fileName, f.packageName, expectedPackage) + assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.FileName(), f.PackageName(), expectedPackage) } func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { @@ -16,9 +16,9 @@ func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { } func (method *Method) AssertNameMatches(t *testing.T, regex *regexp.Regexp) { - assert.Truef(t, regex.MatchString(method.name), "filename %s contains exported method %s which does not match %s", method.file.fileName, method.name, regex.String()) + assert.Truef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which does not match %s", method.FileName(), method.Name(), regex.String()) } func (method *Method) AssertNameDoesNotMatch(t *testing.T, regex *regexp.Regexp) { - assert.Falsef(t, regex.MatchString(method.name), "filename %s contains exported method %s which matches %s", method.file.fileName, method.name, regex.String()) + assert.Falsef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which matches %s", method.FileName(), method.Name(), regex.String()) } diff --git a/pkg/architest/file.go b/pkg/architest/file.go index e0d25020af..279c4e78ae 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -2,6 +2,9 @@ package architest import ( "go/ast" + "go/parser" + "go/token" + "path/filepath" "regexp" ) @@ -46,6 +49,14 @@ func NewFile(packageName string, fileName string, fileSrc *ast.File) *File { } } +func NewFileFromPath(path string) *File { + file, err := parser.ParseFile(token.NewFileSet(), path, nil, 0) + if err != nil { + panic(err) + } + return NewFile(file.Name.Name, filepath.Base(path), file) +} + func (f *File) PackageName() string { return f.packageName } diff --git a/pkg/architest/method.go b/pkg/architest/method.go index 21360a2004..92908a0703 100644 --- a/pkg/architest/method.go +++ b/pkg/architest/method.go @@ -5,6 +5,14 @@ type Method struct { file *File } +func (method *Method) Name() string { + return method.name +} + +func (method *Method) FileName() string { + return method.file.FileName() +} + func NewMethod(name string, file *File) *Method { return &Method{ name: name, diff --git a/pkg/architest/testdata/dir1/sample2.go b/pkg/architest/testdata/dir1/sample2.go index b719eadc09..7ba18f8743 100644 --- a/pkg/architest/testdata/dir1/sample2.go +++ b/pkg/architest/testdata/dir1/sample2.go @@ -1 +1,5 @@ package dir1 + +func A() {} + +func a() {} From 6204e8a39f251788c662bfa7545b90789fc722e2 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 19:35:46 +0100 Subject: [PATCH 20/32] Test file filtering --- pkg/architest/architest_test.go | 38 +++++++++++++++++-- pkg/architest/directory.go | 27 +++++++------ pkg/architest/file.go | 21 ++-------- pkg/architest/file_filter_providers.go | 14 ++++++- pkg/architest/testdata/dir1/different1.go | 1 + .../datasources_acceptance_tests_arch_test.go | 4 +- .../resources_acceptance_tests_arch_test.go | 4 +- 7 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 pkg/architest/testdata/dir1/different1.go diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 6c1df6b87c..cb9f2068c0 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -1,24 +1,24 @@ package architest_test import ( + "regexp" "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" "github.com/stretchr/testify/assert" ) -// TODO: create jira issue in tests stabilization (+one-pager?) func Test_Directory(t *testing.T) { - tests := []struct { + tests1 := []struct { directory string expectedFileNames []string expectedPackageNames []string }{ - {directory: "testdata/dir1", expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"}, expectedPackageNames: []string{"dir1"}}, + {directory: "testdata/dir1", expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go", "testdata/dir1/different1.go"}, expectedPackageNames: []string{"dir1"}}, {directory: "testdata/dir2", expectedFileNames: []string{"testdata/dir2/sample1.go", "testdata/dir2/sample1_test.go"}, expectedPackageNames: []string{"dir2", "dir2_test"}}, {directory: "testdata/dir3", expectedFileNames: []string{"testdata/dir3/sample1.go", "testdata/dir3/sample1_acceptance_test.go"}, expectedPackageNames: []string{"dir3", "dir3_test"}}, } - for _, tt := range tests { + for _, tt := range tests1 { t.Run("list all files in the given directory", func(t *testing.T) { dir := architest.NewDirectory(tt.directory) @@ -41,6 +41,36 @@ func Test_Directory(t *testing.T) { } }) } + + tests2 := []struct { + directory string + filter architest.FileFilter + expectedFileNames []string + }{ + {directory: "testdata/dir1", filter: architest.FileNameFilterProvider("sample"), expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"}}, + {directory: "testdata/dir1", filter: architest.FileNameRegexFilterProvider(regexp.MustCompile("sample")), expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go"}}, + {directory: "testdata/dir1", filter: architest.FileNameFilterWithExclusionsProvider(regexp.MustCompile("sample"), regexp.MustCompile("sample1")), expectedFileNames: []string{"testdata/dir1/sample2.go"}}, + {directory: "testdata/dir2", filter: architest.PackageFilterProvider("dir2"), expectedFileNames: []string{"testdata/dir2/sample1.go"}}, + {directory: "testdata/dir2", filter: architest.PackageFilterProvider("dir2_test"), expectedFileNames: []string{"testdata/dir2/sample1_test.go"}}, + {directory: "testdata/dir2", filter: architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex), expectedFileNames: []string{}}, + {directory: "testdata/dir3", filter: architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex), expectedFileNames: []string{"testdata/dir3/sample1_acceptance_test.go"}}, + {directory: "testdata/dir2", filter: architest.FileNameRegexFilterProvider(architest.TestFileRegex), expectedFileNames: []string{"testdata/dir2/sample1_test.go"}}, + {directory: "testdata/dir3", filter: architest.FileNameRegexFilterProvider(architest.TestFileRegex), expectedFileNames: []string{"testdata/dir3/sample1_acceptance_test.go"}}, + } + for _, tt := range tests2 { + t.Run("list only files matching filter in the given directory", func(t *testing.T) { + dir := architest.NewDirectory(tt.directory) + + filteredFiles := dir.Files(tt.filter) + assert.Len(t, filteredFiles, len(tt.expectedFileNames)) + + fileNames := make([]string, 0, len(filteredFiles)) + for _, f := range filteredFiles { + fileNames = append(fileNames, f.FileName()) + } + assert.ElementsMatch(t, fileNames, tt.expectedFileNames) + }) + } } func Test_Files(t *testing.T) { diff --git a/pkg/architest/directory.go b/pkg/architest/directory.go index 1036fb08a5..1787680f6b 100644 --- a/pkg/architest/directory.go +++ b/pkg/architest/directory.go @@ -3,23 +3,15 @@ package architest import ( "go/parser" "go/token" - "io/fs" ) type Directory struct { - path string + path string + files Files } func NewDirectory(path string) *Directory { - return &Directory{path: path} -} - -func (d *Directory) AllFiles() Files { - return d.files(nil) -} - -func (d *Directory) files(filter func(fi fs.FileInfo) bool) Files { - packagesDict, err := parser.ParseDir(token.NewFileSet(), d.path, filter, 0) + packagesDict, err := parser.ParseDir(token.NewFileSet(), path, nil, 0) if err != nil { panic(err) } @@ -29,5 +21,16 @@ func (d *Directory) files(filter func(fi fs.FileInfo) bool) Files { files = append(files, *NewFile(packageName, fileName, fileSrc)) } } - return files + return &Directory{ + path: path, + files: files, + } +} + +func (d *Directory) AllFiles() Files { + return d.files +} + +func (d *Directory) Files(filter FileFilter) Files { + return d.AllFiles().Filter(filter) } diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 279c4e78ae..05b494d436 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -16,23 +16,10 @@ var ( ) func init() { - var err error - AcceptanceTestFileRegex, err = regexp.Compile("^.*_acceptance_test.go$") - if err != nil { - panic(err) - } - AcceptanceTestNameRegex, err = regexp.Compile("^TestAcc_.*$") - if err != nil { - panic(err) - } - TestFileRegex, err = regexp.Compile("^.*_test.go$") - if err != nil { - panic(err) - } - TestNameRegex, err = regexp.Compile("^Test.*$") - if err != nil { - panic(err) - } + AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") + AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.*$") + TestFileRegex = regexp.MustCompile("^.*_test.go$") + TestNameRegex = regexp.MustCompile("^Test.*$") } type File struct { diff --git a/pkg/architest/file_filter_providers.go b/pkg/architest/file_filter_providers.go index bb2279488d..7e1ff457dc 100644 --- a/pkg/architest/file_filter_providers.go +++ b/pkg/architest/file_filter_providers.go @@ -1,8 +1,18 @@ package architest -import "regexp" +import ( + "fmt" + "regexp" +) -func FileNameFilterProvider(regex *regexp.Regexp) FileFilter { +func FileNameFilterProvider(text string) FileFilter { + return func(f *File) bool { + regex := regexp.MustCompile(fmt.Sprintf(`^.*%s.*$`, text)) + return regex.Match([]byte(f.fileName)) + } +} + +func FileNameRegexFilterProvider(regex *regexp.Regexp) FileFilter { return func(f *File) bool { return regex.Match([]byte(f.fileName)) } diff --git a/pkg/architest/testdata/dir1/different1.go b/pkg/architest/testdata/dir1/different1.go new file mode 100644 index 0000000000..b719eadc09 --- /dev/null +++ b/pkg/architest/testdata/dir1/different1.go @@ -0,0 +1 @@ +package dir1 diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index baa13c39d6..67f4f30479 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -11,7 +11,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { datasourcesFiles := datasourcesDirectory.AllFiles() t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { file.AssertHasPackage(t, "datasources_test") @@ -19,7 +19,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 5efebb566d..86ccd67584 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -11,7 +11,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { resourcesFiles := resourcesDirectory.AllFiles() t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { file.AssertHasPackage(t, "resources_test") @@ -19,7 +19,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameFilterProvider(architest.AcceptanceTestFileRegex)) + acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) acceptanceTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { From d73890116cda0542f40e40b7db66519310eb18f0 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 19:47:42 +0100 Subject: [PATCH 21/32] Add tests for package assertions --- pkg/architest/architest_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index cb9f2068c0..9ba1ef5393 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -96,3 +96,27 @@ func Test_Files(t *testing.T) { }) } } + +func Test_Assertions(t *testing.T) { + tests := []struct { + filePath string + expectedPackage string + }{ + {filePath: "testdata/dir1/sample1.go", expectedPackage: "dir1"}, + {filePath: "testdata/dir2/sample1.go", expectedPackage: "dir2"}, + {filePath: "testdata/dir2/sample1_test.go", expectedPackage: "dir2_test"}, + } + for _, tt := range tests { + t.Run("file package assertions", func(t *testing.T) { + file := architest.NewFileFromPath(tt.filePath) + tut1 := &testing.T{} + tut2 := &testing.T{} + + file.AssertHasPackage(tut1, tt.expectedPackage) + file.AssertHasPackage(tut2, "some_other_package") + + assert.Equal(t, false, tut1.Failed()) + assert.Equal(t, true, tut2.Failed()) + }) + } +} From b541e591803b977ceda6ee5fa8abb96a6c8e2e72 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 20:04:32 +0100 Subject: [PATCH 22/32] Test rest of the assertions --- pkg/architest/architest_test.go | 74 ++++++++++++++++++++++++++++++++- pkg/architest/assertions.go | 4 ++ pkg/architest/file.go | 2 +- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 9ba1ef5393..324533d861 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -1,6 +1,7 @@ package architest_test import ( + "fmt" "regexp" "testing" @@ -98,7 +99,7 @@ func Test_Files(t *testing.T) { } func Test_Assertions(t *testing.T) { - tests := []struct { + tests1 := []struct { filePath string expectedPackage string }{ @@ -106,7 +107,7 @@ func Test_Assertions(t *testing.T) { {filePath: "testdata/dir2/sample1.go", expectedPackage: "dir2"}, {filePath: "testdata/dir2/sample1_test.go", expectedPackage: "dir2_test"}, } - for _, tt := range tests { + for _, tt := range tests1 { t.Run("file package assertions", func(t *testing.T) { file := architest.NewFileFromPath(tt.filePath) tut1 := &testing.T{} @@ -119,4 +120,73 @@ func Test_Assertions(t *testing.T) { assert.Equal(t, true, tut2.Failed()) }) } + + tests2 := []struct { + methodName string + correct bool + }{ + {methodName: "TestAcc_abc", correct: true}, + {methodName: "TestAcc_TestAcc_Test", correct: true}, + {methodName: "TestAcc_", correct: false}, + {methodName: "ATestAcc_", correct: false}, + {methodName: "TestAcc", correct: false}, + {methodName: "Test_", correct: false}, + {methodName: "TestAccc_", correct: false}, + } + for _, tt := range tests2 { + t.Run(fmt.Sprintf("acceptance test name assertions for method %s", tt.methodName), func(t *testing.T) { + file := architest.NewFileFromPath("testdata/dir1/sample1.go") + method := architest.NewMethod(tt.methodName, file) + tut := &testing.T{} + + method.AssertAcceptanceTestNamedCorrectly(tut) + + assert.Equal(t, !tt.correct, tut.Failed()) + }) + } + + tests3 := []struct { + methodName string + regexRaw string + correct bool + }{ + {methodName: "sample1", regexRaw: "sample", correct: true}, + {methodName: "Sample1", regexRaw: "sample", correct: false}, + {methodName: "Sample1", regexRaw: "Sample", correct: true}, + } + for _, tt := range tests3 { + t.Run(fmt.Sprintf("matching and not matching method name assertions for %s", tt.methodName), func(t *testing.T) { + file := architest.NewFileFromPath("testdata/dir1/sample1.go") + method := architest.NewMethod(tt.methodName, file) + tut1 := &testing.T{} + tut2 := &testing.T{} + + method.AssertNameMatches(tut1, regexp.MustCompile(tt.regexRaw)) + method.AssertNameDoesNotMatch(tut2, regexp.MustCompile(tt.regexRaw)) + + assert.Equal(t, !tt.correct, tut1.Failed()) + assert.Equal(t, tt.correct, tut2.Failed()) + }) + } + + tests4 := []struct { + methodName string + correct bool + }{ + {methodName: "Test", correct: true}, + {methodName: "aTest", correct: false}, + {methodName: "Test_", correct: true}, + {methodName: "Test_adsfadf", correct: true}, + } + for _, tt := range tests4 { + t.Run(fmt.Sprintf("test name assertions for method %s", tt.methodName), func(t *testing.T) { + file := architest.NewFileFromPath("testdata/dir1/sample1.go") + method := architest.NewMethod(tt.methodName, file) + tut := &testing.T{} + + method.AssertTestNamedCorrectly(tut) + + assert.Equal(t, !tt.correct, tut.Failed()) + }) + } } diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index 89cbec6843..48bb0af5df 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -15,6 +15,10 @@ func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { method.AssertNameMatches(t, AcceptanceTestNameRegex) } +func (method *Method) AssertTestNamedCorrectly(t *testing.T) { + method.AssertNameMatches(t, TestNameRegex) +} + func (method *Method) AssertNameMatches(t *testing.T, regex *regexp.Regexp) { assert.Truef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which does not match %s", method.FileName(), method.Name(), regex.String()) } diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 05b494d436..47469c376d 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -17,7 +17,7 @@ var ( func init() { AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") - AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.*$") + AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") TestFileRegex = regexp.MustCompile("^.*_test.go$") TestNameRegex = regexp.MustCompile("^Test.*$") } From 265e73a3cbed90578132ecb563497a9ec4544fc0 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 20:18:00 +0100 Subject: [PATCH 23/32] Test invocation on every file and method --- pkg/architest/architest_test.go | 62 +++++++++++++++++-- pkg/architest/assertions.go | 2 +- pkg/architest/file.go | 2 +- pkg/architest/method.go | 2 +- .../datasources_acceptance_tests_arch_test.go | 2 +- .../resources_acceptance_tests_arch_test.go | 2 +- 6 files changed, 63 insertions(+), 9 deletions(-) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 324533d861..346300d885 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -28,7 +28,7 @@ func Test_Directory(t *testing.T) { fileNames := make([]string, 0, len(allFiles)) for _, f := range allFiles { - fileNames = append(fileNames, f.FileName()) + fileNames = append(fileNames, f.Name()) } assert.ElementsMatch(t, fileNames, tt.expectedFileNames) @@ -67,7 +67,7 @@ func Test_Directory(t *testing.T) { fileNames := make([]string, 0, len(filteredFiles)) for _, f := range filteredFiles { - fileNames = append(fileNames, f.FileName()) + fileNames = append(fileNames, f.Name()) } assert.ElementsMatch(t, fileNames, tt.expectedFileNames) }) @@ -75,14 +75,14 @@ func Test_Directory(t *testing.T) { } func Test_Files(t *testing.T) { - tests := []struct { + tests1 := []struct { filePath string expectedMethodNames []string }{ {filePath: "testdata/dir1/sample1.go", expectedMethodNames: []string{}}, {filePath: "testdata/dir1/sample2.go", expectedMethodNames: []string{"A"}}, } - for _, tt := range tests { + for _, tt := range tests1 { t.Run("list all methods in file", func(t *testing.T) { file := architest.NewFileFromPath(tt.filePath) @@ -96,6 +96,60 @@ func Test_Files(t *testing.T) { assert.ElementsMatch(t, methodNames, tt.expectedMethodNames) }) } + + tests2 := []struct { + fileNames []string + }{ + {fileNames: []string{}}, + {fileNames: []string{"a"}}, + {fileNames: []string{"a", "A"}}, + {fileNames: []string{"A", "a"}}, + {fileNames: []string{"A", "B", "C"}}, + } + for _, tt := range tests2 { + t.Run("receiver invoked for every file", func(t *testing.T) { + files := make(architest.Files, 0, len(tt.fileNames)) + for _, f := range tt.fileNames { + files = append(files, *architest.NewFile("package", f, nil)) + } + invokedFiles := make([]string, 0) + receiver := func(f *architest.File) { + invokedFiles = append(invokedFiles, f.Name()) + } + + files.All(receiver) + + assert.ElementsMatch(t, tt.fileNames, invokedFiles) + }) + } +} + +func Test_Methods(t *testing.T) { + tests := []struct { + methodNames []string + }{ + {methodNames: []string{}}, + {methodNames: []string{"a"}}, + {methodNames: []string{"a", "A"}}, + {methodNames: []string{"A", "a"}}, + {methodNames: []string{"A", "B", "C"}}, + } + for _, tt := range tests { + t.Run("receiver invoked for every method", func(t *testing.T) { + methods := make(architest.Methods, 0, len(tt.methodNames)) + for _, m := range tt.methodNames { + methods = append(methods, *architest.NewMethod(m, nil)) + } + invokedMethods := make([]string, 0) + receiver := func(m *architest.Method) { + invokedMethods = append(invokedMethods, m.Name()) + } + + methods.All(receiver) + + assert.ElementsMatch(t, tt.methodNames, invokedMethods) + }) + } } func Test_Assertions(t *testing.T) { diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index 48bb0af5df..1f551e7dfa 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -8,7 +8,7 @@ import ( ) func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { - assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.FileName(), f.PackageName(), expectedPackage) + assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.Name(), f.PackageName(), expectedPackage) } func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 47469c376d..29510a3d12 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -48,7 +48,7 @@ func (f *File) PackageName() string { return f.packageName } -func (f *File) FileName() string { +func (f *File) Name() string { return f.fileName } diff --git a/pkg/architest/method.go b/pkg/architest/method.go index 92908a0703..17bbe597c3 100644 --- a/pkg/architest/method.go +++ b/pkg/architest/method.go @@ -10,7 +10,7 @@ func (method *Method) Name() string { } func (method *Method) FileName() string { - return method.file.FileName() + return method.file.Name() } func NewMethod(name string, file *File) *Method { diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index 67f4f30479..754ceef740 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -34,7 +34,7 @@ func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) - method.AssertNameMatches(t, architest.TestNameRegex) + method.AssertTestNamedCorrectly(t) }) }) }) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 86ccd67584..1770ca19b3 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -34,7 +34,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { otherTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { method.AssertNameDoesNotMatch(t, architest.AcceptanceTestNameRegex) - method.AssertNameMatches(t, architest.TestNameRegex) + method.AssertTestNamedCorrectly(t) }) }) }) From 68531d8d6adbe34e1d9240ce1a2f517ee01783b8 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 20:26:13 +0100 Subject: [PATCH 24/32] Test creation of directory and file --- pkg/architest/architest_test.go | 34 +++++++++++++++++++++++++++++++++ pkg/architest/file.go | 15 --------------- pkg/architest/regex.go | 17 +++++++++++++++++ 3 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 pkg/architest/regex.go diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 346300d885..5f1f6c8868 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -10,6 +10,18 @@ import ( ) func Test_Directory(t *testing.T) { + t.Run("fail to create directory", func(t *testing.T) { + assert.Panics(t, func() { + architest.NewDirectory("testdata/non_existing") + }) + }) + + t.Run("create directory", func(t *testing.T) { + assert.NotPanics(t, func() { + architest.NewDirectory("testdata/dir1") + }) + }) + tests1 := []struct { directory string expectedFileNames []string @@ -70,11 +82,33 @@ func Test_Directory(t *testing.T) { fileNames = append(fileNames, f.Name()) } assert.ElementsMatch(t, fileNames, tt.expectedFileNames) + + // now exactly the same but indirectly + filteredFiles = dir.AllFiles().Filter(tt.filter) + assert.Len(t, filteredFiles, len(tt.expectedFileNames)) + + fileNames = make([]string, 0, len(filteredFiles)) + for _, f := range filteredFiles { + fileNames = append(fileNames, f.Name()) + } + assert.ElementsMatch(t, fileNames, tt.expectedFileNames) }) } } func Test_Files(t *testing.T) { + t.Run("fail to create file", func(t *testing.T) { + assert.Panics(t, func() { + architest.NewFileFromPath("testdata/dir1/non_existing.go") + }) + }) + + t.Run("create file", func(t *testing.T) { + assert.NotPanics(t, func() { + architest.NewFileFromPath("testdata/dir1/sample1.go") + }) + }) + tests1 := []struct { filePath string expectedMethodNames []string diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 29510a3d12..62f62d7941 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -5,23 +5,8 @@ import ( "go/parser" "go/token" "path/filepath" - "regexp" ) -var ( - AcceptanceTestFileRegex *regexp.Regexp - AcceptanceTestNameRegex *regexp.Regexp - TestFileRegex *regexp.Regexp - TestNameRegex *regexp.Regexp -) - -func init() { - AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") - AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") - TestFileRegex = regexp.MustCompile("^.*_test.go$") - TestNameRegex = regexp.MustCompile("^Test.*$") -} - type File struct { packageName string fileName string diff --git a/pkg/architest/regex.go b/pkg/architest/regex.go new file mode 100644 index 0000000000..998892c144 --- /dev/null +++ b/pkg/architest/regex.go @@ -0,0 +1,17 @@ +package architest + +import "regexp" + +var ( + AcceptanceTestFileRegex *regexp.Regexp + AcceptanceTestNameRegex *regexp.Regexp + TestFileRegex *regexp.Regexp + TestNameRegex *regexp.Regexp +) + +func init() { + AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") + AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") + TestFileRegex = regexp.MustCompile("^.*_test.go$") + TestNameRegex = regexp.MustCompile("^Test.*$") +} From 83d1875c43c82210a4e9f5674827c094a42fbe84 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 20:41:27 +0100 Subject: [PATCH 25/32] Add tests for sdk integration tests --- pkg/architest/assertions.go | 10 ++++ pkg/architest/regex.go | 12 +++-- .../sdk_integration_tests_arch_test.go | 54 +++++++++++++++++++ pkg/sdk/testint/parsers.go | 2 +- .../resource_monitors_integration_test.go | 4 +- .../{setup_integration_test.go => setup.go} | 0 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 pkg/architests/sdk_integration_tests_arch_test.go rename pkg/sdk/testint/{setup_integration_test.go => setup.go} (100%) diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index 1f551e7dfa..54bdb860aa 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -8,21 +8,31 @@ import ( ) func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { + t.Helper() assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.Name(), f.PackageName(), expectedPackage) } func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { + t.Helper() method.AssertNameMatches(t, AcceptanceTestNameRegex) } +func (method *Method) AssertIntegrationTestNamedCorrectly(t *testing.T) { + t.Helper() + method.AssertNameMatches(t, IntegrationTestNameRegex) +} + func (method *Method) AssertTestNamedCorrectly(t *testing.T) { + t.Helper() method.AssertNameMatches(t, TestNameRegex) } func (method *Method) AssertNameMatches(t *testing.T, regex *regexp.Regexp) { + t.Helper() assert.Truef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which does not match %s", method.FileName(), method.Name(), regex.String()) } func (method *Method) AssertNameDoesNotMatch(t *testing.T, regex *regexp.Regexp) { + t.Helper() assert.Falsef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which matches %s", method.FileName(), method.Name(), regex.String()) } diff --git a/pkg/architest/regex.go b/pkg/architest/regex.go index 998892c144..a0810ef21e 100644 --- a/pkg/architest/regex.go +++ b/pkg/architest/regex.go @@ -3,15 +3,19 @@ package architest import "regexp" var ( - AcceptanceTestFileRegex *regexp.Regexp - AcceptanceTestNameRegex *regexp.Regexp - TestFileRegex *regexp.Regexp - TestNameRegex *regexp.Regexp + AcceptanceTestFileRegex *regexp.Regexp + AcceptanceTestNameRegex *regexp.Regexp + IntegrationTestFileRegex *regexp.Regexp + IntegrationTestNameRegex *regexp.Regexp + TestFileRegex *regexp.Regexp + TestNameRegex *regexp.Regexp ) func init() { AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") + IntegrationTestFileRegex = regexp.MustCompile("^.*_integration_test.go$") + IntegrationTestNameRegex = regexp.MustCompile("^TestInt_.+$") TestFileRegex = regexp.MustCompile("^.*_test.go$") TestNameRegex = regexp.MustCompile("^Test.*$") } diff --git a/pkg/architests/sdk_integration_tests_arch_test.go b/pkg/architests/sdk_integration_tests_arch_test.go new file mode 100644 index 0000000000..48c2ef3a86 --- /dev/null +++ b/pkg/architests/sdk_integration_tests_arch_test.go @@ -0,0 +1,54 @@ +package architests + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" +) + +func TestArchCheck_IntegrationTests_Sdk(t *testing.T) { + sdkIntegrationTestDirectory := architest.NewDirectory("../sdk/testint/") + sdkIntegrationTestFiles := sdkIntegrationTestDirectory.AllFiles() + + t.Run("integration tests files have the right package", func(t *testing.T) { + integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) + + integrationTestFiles.All(func(file *architest.File) { + file.AssertHasPackage(t, "testint") + }) + }) + + t.Run("integration tests are named correctly", func(t *testing.T) { + integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) + + integrationTestFiles.All(func(file *architest.File) { + file.ExportedMethods().All(func(method *architest.Method) { + method.AssertIntegrationTestNamedCorrectly(t) + }) + }) + }) + + t.Run("there are no integration tests in other test files in the directory", func(t *testing.T) { + otherTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.IntegrationTestFileRegex)) + + otherTestFiles.All(func(file *architest.File) { + file.ExportedMethods().All(func(method *architest.Method) { + method.AssertNameDoesNotMatch(t, architest.IntegrationTestNameRegex) + method.AssertTestNamedCorrectly(t) + }) + }) + }) + + t.Run("there are only integration tests in package testint", func(t *testing.T) { + packageFiles := sdkIntegrationTestFiles.Filter(architest.PackageFilterProvider("testint")) + + packageFiles.All(func(file *architest.File) { + file.ExportedMethods().All(func(method *architest.Method) { + // our integration tests have TestMain, let's filter it out now (maybe later we can support in in architest) + if method.Name() != "TestMain" { + method.AssertIntegrationTestNamedCorrectly(t) + } + }) + }) + }) +} diff --git a/pkg/sdk/testint/parsers.go b/pkg/sdk/testint/parsers.go index 86d8a90fef..99114fb599 100644 --- a/pkg/sdk/testint/parsers.go +++ b/pkg/sdk/testint/parsers.go @@ -2,7 +2,7 @@ package testint import "time" -func ParseTimestampWithOffset(s string) (*time.Time, error) { +func parseTimestampWithOffset(s string) (*time.Time, error) { t, err := time.Parse("2006-01-02T15:04:05-07:00", s) if err != nil { return nil, err diff --git a/pkg/sdk/testint/resource_monitors_integration_test.go b/pkg/sdk/testint/resource_monitors_integration_test.go index 86e19aa5fc..904a198c8d 100644 --- a/pkg/sdk/testint/resource_monitors_integration_test.go +++ b/pkg/sdk/testint/resource_monitors_integration_test.go @@ -235,9 +235,9 @@ func TestInt_ResourceMonitorAlter(t *testing.T) { assert.Equal(t, 1, len(resourceMonitors)) resourceMonitor = &resourceMonitors[0] assert.Equal(t, *frequency, resourceMonitor.Frequency) - startTime, err := ParseTimestampWithOffset(resourceMonitor.StartTime) + startTime, err := parseTimestampWithOffset(resourceMonitor.StartTime) require.NoError(t, err) - endTime, err := ParseTimestampWithOffset(resourceMonitor.EndTime) + endTime, err := parseTimestampWithOffset(resourceMonitor.EndTime) require.NoError(t, err) assert.Equal(t, startTimeStamp, startTime.Format("2006-01-01 15:04")) assert.Equal(t, endTimeStamp, endTime.Format("2006-01-01 15:04")) diff --git a/pkg/sdk/testint/setup_integration_test.go b/pkg/sdk/testint/setup.go similarity index 100% rename from pkg/sdk/testint/setup_integration_test.go rename to pkg/sdk/testint/setup.go From bd33dd58dad2d4d7464966dc107c35f4b82ff600 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 20:49:23 +0100 Subject: [PATCH 26/32] Add tests integration tests matchers --- pkg/architest/architest_test.go | 36 +++++++++++++++++++ pkg/architest/testdata/dir4/sample1.go | 1 + .../testdata/dir4/sample1_integration_test.go | 1 + 3 files changed, 38 insertions(+) create mode 100644 pkg/architest/testdata/dir4/sample1.go create mode 100644 pkg/architest/testdata/dir4/sample1_integration_test.go diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 5f1f6c8868..5d892a12a2 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -30,6 +30,7 @@ func Test_Directory(t *testing.T) { {directory: "testdata/dir1", expectedFileNames: []string{"testdata/dir1/sample1.go", "testdata/dir1/sample2.go", "testdata/dir1/different1.go"}, expectedPackageNames: []string{"dir1"}}, {directory: "testdata/dir2", expectedFileNames: []string{"testdata/dir2/sample1.go", "testdata/dir2/sample1_test.go"}, expectedPackageNames: []string{"dir2", "dir2_test"}}, {directory: "testdata/dir3", expectedFileNames: []string{"testdata/dir3/sample1.go", "testdata/dir3/sample1_acceptance_test.go"}, expectedPackageNames: []string{"dir3", "dir3_test"}}, + {directory: "testdata/dir4", expectedFileNames: []string{"testdata/dir4/sample1.go", "testdata/dir4/sample1_integration_test.go"}, expectedPackageNames: []string{"dir4", "dir4_test"}}, } for _, tt := range tests1 { t.Run("list all files in the given directory", func(t *testing.T) { @@ -67,8 +68,13 @@ func Test_Directory(t *testing.T) { {directory: "testdata/dir2", filter: architest.PackageFilterProvider("dir2_test"), expectedFileNames: []string{"testdata/dir2/sample1_test.go"}}, {directory: "testdata/dir2", filter: architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex), expectedFileNames: []string{}}, {directory: "testdata/dir3", filter: architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex), expectedFileNames: []string{"testdata/dir3/sample1_acceptance_test.go"}}, + {directory: "testdata/dir4", filter: architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex), expectedFileNames: []string{}}, + {directory: "testdata/dir2", filter: architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex), expectedFileNames: []string{}}, + {directory: "testdata/dir3", filter: architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex), expectedFileNames: []string{}}, + {directory: "testdata/dir4", filter: architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex), expectedFileNames: []string{"testdata/dir4/sample1_integration_test.go"}}, {directory: "testdata/dir2", filter: architest.FileNameRegexFilterProvider(architest.TestFileRegex), expectedFileNames: []string{"testdata/dir2/sample1_test.go"}}, {directory: "testdata/dir3", filter: architest.FileNameRegexFilterProvider(architest.TestFileRegex), expectedFileNames: []string{"testdata/dir3/sample1_acceptance_test.go"}}, + {directory: "testdata/dir4", filter: architest.FileNameRegexFilterProvider(architest.TestFileRegex), expectedFileNames: []string{"testdata/dir4/sample1_integration_test.go"}}, } for _, tt := range tests2 { t.Run("list only files matching filter in the given directory", func(t *testing.T) { @@ -219,7 +225,10 @@ func Test_Assertions(t *testing.T) { {methodName: "ATestAcc_", correct: false}, {methodName: "TestAcc", correct: false}, {methodName: "Test_", correct: false}, + {methodName: "Test", correct: false}, + {methodName: "Test_asdf", correct: false}, {methodName: "TestAccc_", correct: false}, + {methodName: "TestInt_Abc", correct: false}, } for _, tt := range tests2 { t.Run(fmt.Sprintf("acceptance test name assertions for method %s", tt.methodName), func(t *testing.T) { @@ -277,4 +286,31 @@ func Test_Assertions(t *testing.T) { assert.Equal(t, !tt.correct, tut.Failed()) }) } + + tests5 := []struct { + methodName string + correct bool + }{ + {methodName: "TestInt_abc", correct: true}, + {methodName: "TestInt_TestInt_Test", correct: true}, + {methodName: "TestInt_", correct: false}, + {methodName: "ATestInt_", correct: false}, + {methodName: "TestInt", correct: false}, + {methodName: "Test_", correct: false}, + {methodName: "Test", correct: false}, + {methodName: "Test_asdf", correct: false}, + {methodName: "TestIntt_", correct: false}, + {methodName: "TestAcc_Abc", correct: false}, + } + for _, tt := range tests5 { + t.Run(fmt.Sprintf("intagration test name assertions for method %s", tt.methodName), func(t *testing.T) { + file := architest.NewFileFromPath("testdata/dir1/sample1.go") + method := architest.NewMethod(tt.methodName, file) + tut := &testing.T{} + + method.AssertIntegrationTestNamedCorrectly(tut) + + assert.Equal(t, !tt.correct, tut.Failed()) + }) + } } diff --git a/pkg/architest/testdata/dir4/sample1.go b/pkg/architest/testdata/dir4/sample1.go new file mode 100644 index 0000000000..5f6819e3fe --- /dev/null +++ b/pkg/architest/testdata/dir4/sample1.go @@ -0,0 +1 @@ +package dir4 diff --git a/pkg/architest/testdata/dir4/sample1_integration_test.go b/pkg/architest/testdata/dir4/sample1_integration_test.go new file mode 100644 index 0000000000..20634accdf --- /dev/null +++ b/pkg/architest/testdata/dir4/sample1_integration_test.go @@ -0,0 +1 @@ +package dir4_test From dd5e885f30e62cdc3e7a405cdd243ad1dee32bdf Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 21:07:43 +0100 Subject: [PATCH 27/32] Fix lint and stuff --- Makefile | 6 +++--- pkg/architest/file.go | 5 ++--- pkg/architest/files.go | 10 +++++++--- pkg/architest/methods.go | 7 +++++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 0b2a2fc7d9..48b0efe3a1 100644 --- a/Makefile +++ b/Makefile @@ -38,10 +38,10 @@ install: ## install the binary go install -v ./... lint: # Run static code analysis, check formatting. See https://golangci-lint.run/ - golangci-lint run ./... -v + ./bin/golangci-lint run ./... -v lint-fix: ## Run static code analysis, check formatting and try to fix findings - golangci-lint run ./... -v --fix + ./bin/golangci-lint run ./... -v --fix mod: ## add missing and remove unused modules go mod tidy -compat=1.20 @@ -49,7 +49,7 @@ mod: ## add missing and remove unused modules mod-check: mod ## check if there are any missing/unused modules git diff --exit-code -- go.mod go.sum -pre-push: fmt docs mod lint ## Run a few checks before pushing a change (docs, fmt, mod, etc.) +pre-push: fmt docs mod lint ## Run a few checks before pushing a change (docs, fmt, mod, etc.) pre-push-check: fmt-check docs-check lint-check mod-check ## Run a few checks before pushing a change (docs, fmt, mod, etc.) diff --git a/pkg/architest/file.go b/pkg/architest/file.go index 62f62d7941..a2d781a719 100644 --- a/pkg/architest/file.go +++ b/pkg/architest/file.go @@ -40,9 +40,8 @@ func (f *File) Name() string { func (f *File) ExportedMethods() Methods { allExportedMethods := make(Methods, 0) for _, d := range f.fileSrc.Decls { - switch d.(type) { - case *ast.FuncDecl: - name := d.(*ast.FuncDecl).Name.Name + if v, ok := d.(*ast.FuncDecl); ok { + name := v.Name.Name if ast.IsExported(name) { allExportedMethods = append(allExportedMethods, *NewMethod(name, f)) } diff --git a/pkg/architest/files.go b/pkg/architest/files.go index 4462d01485..6b73d2b039 100644 --- a/pkg/architest/files.go +++ b/pkg/architest/files.go @@ -1,12 +1,15 @@ package architest -type FileFilter = func(*File) bool -type FileReceiver = func(*File) -type Files []File +type ( + FileFilter = func(*File) bool + FileReceiver = func(*File) + Files []File +) func (files Files) Filter(filter FileFilter) Files { filteredFiles := make([]File, 0) for _, f := range files { + f := f if filter(&f) { filteredFiles = append(filteredFiles, f) } @@ -16,6 +19,7 @@ func (files Files) Filter(filter FileFilter) Files { func (files Files) All(receiver FileReceiver) { for _, file := range files { + file := file receiver(&file) } } diff --git a/pkg/architest/methods.go b/pkg/architest/methods.go index e737ae1d5b..b94f8a8d75 100644 --- a/pkg/architest/methods.go +++ b/pkg/architest/methods.go @@ -1,10 +1,13 @@ package architest -type MethodReceiver = func(method *Method) -type Methods []Method +type ( + MethodReceiver = func(method *Method) + Methods []Method +) func (methods Methods) All(receiver MethodReceiver) { for _, method := range methods { + method := method receiver(&method) } } From ff5f5b7ffa61b0e7b154272ef33d7c2a83eba80e Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 21:19:09 +0100 Subject: [PATCH 28/32] Add sample usage --- pkg/architest/architest_test.go | 41 +++++++++++++++++++ pkg/architest/testdata/dir2/sample1_test.go | 6 +++ .../testdata/dir3/sample1_acceptance_test.go | 6 +++ .../testdata/dir4/sample1_integration_test.go | 6 +++ 4 files changed, 59 insertions(+) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index 5d892a12a2..f58021c39a 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -314,3 +314,44 @@ func Test_Assertions(t *testing.T) { }) } } + +func Test_SampleArchiTestUsage(t *testing.T) { + t.Run("acceptance tests", func(t *testing.T) { + acceptanceTestFiles := architest.NewDirectory("testdata/dir3/"). + AllFiles(). + Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) + + acceptanceTestFiles.All(func(file *architest.File) { + file.AssertHasPackage(t, "dir3_test") + file.ExportedMethods().All(func(method *architest.Method) { + method.AssertAcceptanceTestNamedCorrectly(t) + }) + }) + }) + + t.Run("integration tests", func(t *testing.T) { + integrationTestFiles := architest.NewDirectory("testdata/dir4/"). + AllFiles(). + Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) + + integrationTestFiles.All(func(file *architest.File) { + file.AssertHasPackage(t, "dir4_test") + file.ExportedMethods().All(func(method *architest.Method) { + method.AssertIntegrationTestNamedCorrectly(t) + }) + }) + }) + + t.Run("tests", func(t *testing.T) { + testFiles := architest.NewDirectory("testdata/dir2/"). + AllFiles(). + Filter(architest.FileNameRegexFilterProvider(architest.TestNameRegex)) + + testFiles.All(func(file *architest.File) { + file.AssertHasPackage(t, "dir2_test") + file.ExportedMethods().All(func(method *architest.Method) { + method.AssertTestNamedCorrectly(t) + }) + }) + }) +} diff --git a/pkg/architest/testdata/dir2/sample1_test.go b/pkg/architest/testdata/dir2/sample1_test.go index 3a1d6c990c..f263d411f3 100644 --- a/pkg/architest/testdata/dir2/sample1_test.go +++ b/pkg/architest/testdata/dir2/sample1_test.go @@ -1 +1,7 @@ package dir2_test + +import "testing" + +func Test(t *testing.T) { + t.Skip("Test for example purposes") +} diff --git a/pkg/architest/testdata/dir3/sample1_acceptance_test.go b/pkg/architest/testdata/dir3/sample1_acceptance_test.go index d3ddb6dea6..0eab424337 100644 --- a/pkg/architest/testdata/dir3/sample1_acceptance_test.go +++ b/pkg/architest/testdata/dir3/sample1_acceptance_test.go @@ -1 +1,7 @@ package dir3_test + +import "testing" + +func TestAcc_Abc(t *testing.T) { + t.Skip("Test for example purposes") +} diff --git a/pkg/architest/testdata/dir4/sample1_integration_test.go b/pkg/architest/testdata/dir4/sample1_integration_test.go index 20634accdf..33cedbbf4e 100644 --- a/pkg/architest/testdata/dir4/sample1_integration_test.go +++ b/pkg/architest/testdata/dir4/sample1_integration_test.go @@ -1 +1,7 @@ package dir4_test + +import "testing" + +func TestInt_Abc(t *testing.T) { + t.Skip("Test for example purposes") +} From a68b35de3f7c29f8b74f32773584f4d71e4c0d83 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 23 Nov 2023 21:31:37 +0100 Subject: [PATCH 29/32] Fix test setup --- pkg/sdk/testint/{setup.go => setup_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkg/sdk/testint/{setup.go => setup_test.go} (100%) diff --git a/pkg/sdk/testint/setup.go b/pkg/sdk/testint/setup_test.go similarity index 100% rename from pkg/sdk/testint/setup.go rename to pkg/sdk/testint/setup_test.go From 2a5bed9df384cfb370861cc4e84d9b89e528f1cd Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Tue, 28 Nov 2023 13:49:55 +0100 Subject: [PATCH 30/32] Fix after review --- pkg/architest/architest_test.go | 8 ++++---- pkg/architest/assertions.go | 6 +++--- pkg/architest/file_filter_providers.go | 2 +- pkg/architest/regex.go | 19 +++++-------------- .../datasources_acceptance_tests_arch_test.go | 5 +---- .../resources_acceptance_tests_arch_test.go | 5 +---- .../sdk_integration_tests_arch_test.go | 5 +---- 7 files changed, 16 insertions(+), 34 deletions(-) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index f58021c39a..c80afeebb8 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -10,13 +10,13 @@ import ( ) func Test_Directory(t *testing.T) { - t.Run("fail to create directory", func(t *testing.T) { + t.Run("fail to use non-existing directory", func(t *testing.T) { assert.Panics(t, func() { architest.NewDirectory("testdata/non_existing") }) }) - t.Run("create directory", func(t *testing.T) { + t.Run("use directory", func(t *testing.T) { assert.NotPanics(t, func() { architest.NewDirectory("testdata/dir1") }) @@ -103,13 +103,13 @@ func Test_Directory(t *testing.T) { } func Test_Files(t *testing.T) { - t.Run("fail to create file", func(t *testing.T) { + t.Run("fail to use non-existing file", func(t *testing.T) { assert.Panics(t, func() { architest.NewFileFromPath("testdata/dir1/non_existing.go") }) }) - t.Run("create file", func(t *testing.T) { + t.Run("use file", func(t *testing.T) { assert.NotPanics(t, func() { architest.NewFileFromPath("testdata/dir1/sample1.go") }) diff --git a/pkg/architest/assertions.go b/pkg/architest/assertions.go index 54bdb860aa..41859482de 100644 --- a/pkg/architest/assertions.go +++ b/pkg/architest/assertions.go @@ -9,7 +9,7 @@ import ( func (f *File) AssertHasPackage(t *testing.T, expectedPackage string) { t.Helper() - assert.Equalf(t, expectedPackage, f.packageName, "filename %s has package %s, expected package %s", f.Name(), f.PackageName(), expectedPackage) + assert.Equalf(t, expectedPackage, f.packageName, "file %s has package %s, expected package %s", f.Name(), f.PackageName(), expectedPackage) } func (method *Method) AssertAcceptanceTestNamedCorrectly(t *testing.T) { @@ -29,10 +29,10 @@ func (method *Method) AssertTestNamedCorrectly(t *testing.T) { func (method *Method) AssertNameMatches(t *testing.T, regex *regexp.Regexp) { t.Helper() - assert.Truef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which does not match %s", method.FileName(), method.Name(), regex.String()) + assert.Truef(t, regex.MatchString(method.Name()), "file %s contains exported method %s which does not match %s", method.FileName(), method.Name(), regex.String()) } func (method *Method) AssertNameDoesNotMatch(t *testing.T, regex *regexp.Regexp) { t.Helper() - assert.Falsef(t, regex.MatchString(method.Name()), "filename %s contains exported method %s which matches %s", method.FileName(), method.Name(), regex.String()) + assert.Falsef(t, regex.MatchString(method.Name()), "file %s contains exported method %s which matches %s", method.FileName(), method.Name(), regex.String()) } diff --git a/pkg/architest/file_filter_providers.go b/pkg/architest/file_filter_providers.go index 7e1ff457dc..4f59d07dc0 100644 --- a/pkg/architest/file_filter_providers.go +++ b/pkg/architest/file_filter_providers.go @@ -6,8 +6,8 @@ import ( ) func FileNameFilterProvider(text string) FileFilter { + regex := regexp.MustCompile(fmt.Sprintf(`^.*%s.*$`, text)) return func(f *File) bool { - regex := regexp.MustCompile(fmt.Sprintf(`^.*%s.*$`, text)) return regex.Match([]byte(f.fileName)) } } diff --git a/pkg/architest/regex.go b/pkg/architest/regex.go index a0810ef21e..2876dfed79 100644 --- a/pkg/architest/regex.go +++ b/pkg/architest/regex.go @@ -3,19 +3,10 @@ package architest import "regexp" var ( - AcceptanceTestFileRegex *regexp.Regexp - AcceptanceTestNameRegex *regexp.Regexp - IntegrationTestFileRegex *regexp.Regexp - IntegrationTestNameRegex *regexp.Regexp - TestFileRegex *regexp.Regexp - TestNameRegex *regexp.Regexp -) - -func init() { - AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") - AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") + AcceptanceTestFileRegex = regexp.MustCompile("^.*_acceptance_test.go$") + AcceptanceTestNameRegex = regexp.MustCompile("^TestAcc_.+$") IntegrationTestFileRegex = regexp.MustCompile("^.*_integration_test.go$") IntegrationTestNameRegex = regexp.MustCompile("^TestInt_.+$") - TestFileRegex = regexp.MustCompile("^.*_test.go$") - TestNameRegex = regexp.MustCompile("^Test.*$") -} + TestFileRegex = regexp.MustCompile("^.*_test.go$") + TestNameRegex = regexp.MustCompile("^Test.*$") +) diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index 754ceef740..b7647bd9af 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -9,18 +9,15 @@ import ( func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { datasourcesDirectory := architest.NewDirectory("../datasources/") datasourcesFiles := datasourcesDirectory.AllFiles() + acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) - acceptanceTestFiles.All(func(file *architest.File) { file.AssertHasPackage(t, "datasources_test") }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) - acceptanceTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 1770ca19b3..14ffe19250 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -9,18 +9,15 @@ import ( func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { resourcesDirectory := architest.NewDirectory("../resources/") resourcesFiles := resourcesDirectory.AllFiles() + acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) t.Run("acceptance tests files have the right package", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) - acceptanceTestFiles.All(func(file *architest.File) { file.AssertHasPackage(t, "resources_test") }) }) t.Run("acceptance tests are named correctly", func(t *testing.T) { - acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) - acceptanceTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { method.AssertAcceptanceTestNamedCorrectly(t) diff --git a/pkg/architests/sdk_integration_tests_arch_test.go b/pkg/architests/sdk_integration_tests_arch_test.go index 48c2ef3a86..4d2f45339a 100644 --- a/pkg/architests/sdk_integration_tests_arch_test.go +++ b/pkg/architests/sdk_integration_tests_arch_test.go @@ -9,18 +9,15 @@ import ( func TestArchCheck_IntegrationTests_Sdk(t *testing.T) { sdkIntegrationTestDirectory := architest.NewDirectory("../sdk/testint/") sdkIntegrationTestFiles := sdkIntegrationTestDirectory.AllFiles() + integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) t.Run("integration tests files have the right package", func(t *testing.T) { - integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) - integrationTestFiles.All(func(file *architest.File) { file.AssertHasPackage(t, "testint") }) }) t.Run("integration tests are named correctly", func(t *testing.T) { - integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) - integrationTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { method.AssertIntegrationTestNamedCorrectly(t) From fd56b1395a2c1d9687df56ff79da176ae5f97322 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Tue, 28 Nov 2023 13:53:57 +0100 Subject: [PATCH 31/32] Introduce FilesProvider --- pkg/architest/architest_test.go | 14 +++++++------- pkg/architest/directory.go | 15 ++++++++++----- .../datasources_acceptance_tests_arch_test.go | 3 +-- .../resources_acceptance_tests_arch_test.go | 3 +-- pkg/architests/sdk_integration_tests_arch_test.go | 3 +-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/pkg/architest/architest_test.go b/pkg/architest/architest_test.go index c80afeebb8..419f78c503 100644 --- a/pkg/architest/architest_test.go +++ b/pkg/architest/architest_test.go @@ -12,13 +12,13 @@ import ( func Test_Directory(t *testing.T) { t.Run("fail to use non-existing directory", func(t *testing.T) { assert.Panics(t, func() { - architest.NewDirectory("testdata/non_existing") + architest.Directory("testdata/non_existing") }) }) t.Run("use directory", func(t *testing.T) { assert.NotPanics(t, func() { - architest.NewDirectory("testdata/dir1") + architest.Directory("testdata/dir1") }) }) @@ -34,7 +34,7 @@ func Test_Directory(t *testing.T) { } for _, tt := range tests1 { t.Run("list all files in the given directory", func(t *testing.T) { - dir := architest.NewDirectory(tt.directory) + dir := architest.Directory(tt.directory) allFiles := dir.AllFiles() assert.Len(t, allFiles, len(tt.expectedFileNames)) @@ -78,7 +78,7 @@ func Test_Directory(t *testing.T) { } for _, tt := range tests2 { t.Run("list only files matching filter in the given directory", func(t *testing.T) { - dir := architest.NewDirectory(tt.directory) + dir := architest.Directory(tt.directory) filteredFiles := dir.Files(tt.filter) assert.Len(t, filteredFiles, len(tt.expectedFileNames)) @@ -317,7 +317,7 @@ func Test_Assertions(t *testing.T) { func Test_SampleArchiTestUsage(t *testing.T) { t.Run("acceptance tests", func(t *testing.T) { - acceptanceTestFiles := architest.NewDirectory("testdata/dir3/"). + acceptanceTestFiles := architest.Directory("testdata/dir3/"). AllFiles(). Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) @@ -330,7 +330,7 @@ func Test_SampleArchiTestUsage(t *testing.T) { }) t.Run("integration tests", func(t *testing.T) { - integrationTestFiles := architest.NewDirectory("testdata/dir4/"). + integrationTestFiles := architest.Directory("testdata/dir4/"). AllFiles(). Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) @@ -343,7 +343,7 @@ func Test_SampleArchiTestUsage(t *testing.T) { }) t.Run("tests", func(t *testing.T) { - testFiles := architest.NewDirectory("testdata/dir2/"). + testFiles := architest.Directory("testdata/dir2/"). AllFiles(). Filter(architest.FileNameRegexFilterProvider(architest.TestNameRegex)) diff --git a/pkg/architest/directory.go b/pkg/architest/directory.go index 1787680f6b..d289765632 100644 --- a/pkg/architest/directory.go +++ b/pkg/architest/directory.go @@ -5,12 +5,17 @@ import ( "go/token" ) -type Directory struct { +type directory struct { path string files Files } -func NewDirectory(path string) *Directory { +type FilesProvider interface { + AllFiles() Files + Files(filter FileFilter) Files +} + +func Directory(path string) FilesProvider { packagesDict, err := parser.ParseDir(token.NewFileSet(), path, nil, 0) if err != nil { panic(err) @@ -21,16 +26,16 @@ func NewDirectory(path string) *Directory { files = append(files, *NewFile(packageName, fileName, fileSrc)) } } - return &Directory{ + return &directory{ path: path, files: files, } } -func (d *Directory) AllFiles() Files { +func (d *directory) AllFiles() Files { return d.files } -func (d *Directory) Files(filter FileFilter) Files { +func (d *directory) Files(filter FileFilter) Files { return d.AllFiles().Filter(filter) } diff --git a/pkg/architests/datasources_acceptance_tests_arch_test.go b/pkg/architests/datasources_acceptance_tests_arch_test.go index b7647bd9af..8131db1b8c 100644 --- a/pkg/architests/datasources_acceptance_tests_arch_test.go +++ b/pkg/architests/datasources_acceptance_tests_arch_test.go @@ -7,8 +7,7 @@ import ( ) func TestArchCheck_AcceptanceTests_DataSources(t *testing.T) { - datasourcesDirectory := architest.NewDirectory("../datasources/") - datasourcesFiles := datasourcesDirectory.AllFiles() + datasourcesFiles := architest.Directory("../datasources/").AllFiles() acceptanceTestFiles := datasourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) t.Run("acceptance tests files have the right package", func(t *testing.T) { diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 14ffe19250..008df3df01 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -7,8 +7,7 @@ import ( ) func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { - resourcesDirectory := architest.NewDirectory("../resources/") - resourcesFiles := resourcesDirectory.AllFiles() + resourcesFiles := architest.Directory("../resources/").AllFiles() acceptanceTestFiles := resourcesFiles.Filter(architest.FileNameRegexFilterProvider(architest.AcceptanceTestFileRegex)) t.Run("acceptance tests files have the right package", func(t *testing.T) { diff --git a/pkg/architests/sdk_integration_tests_arch_test.go b/pkg/architests/sdk_integration_tests_arch_test.go index 4d2f45339a..2afb157dfe 100644 --- a/pkg/architests/sdk_integration_tests_arch_test.go +++ b/pkg/architests/sdk_integration_tests_arch_test.go @@ -7,8 +7,7 @@ import ( ) func TestArchCheck_IntegrationTests_Sdk(t *testing.T) { - sdkIntegrationTestDirectory := architest.NewDirectory("../sdk/testint/") - sdkIntegrationTestFiles := sdkIntegrationTestDirectory.AllFiles() + sdkIntegrationTestFiles := architest.Directory("../sdk/testint/").AllFiles() integrationTestFiles := sdkIntegrationTestFiles.Filter(architest.FileNameRegexFilterProvider(architest.IntegrationTestFileRegex)) t.Run("integration tests files have the right package", func(t *testing.T) { From 176a61950552f12cf58dd0a165223079cfb6f7b7 Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Tue, 28 Nov 2023 13:59:15 +0100 Subject: [PATCH 32/32] Add recipe --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 48b0efe3a1..0dd62fbd35 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ mod: ## add missing and remove unused modules mod-check: mod ## check if there are any missing/unused modules git diff --exit-code -- go.mod go.sum -pre-push: fmt docs mod lint ## Run a few checks before pushing a change (docs, fmt, mod, etc.) +pre-push: fmt docs mod lint test-architecture ## Run a few checks before pushing a change (docs, fmt, mod, etc.) pre-push-check: fmt-check docs-check lint-check mod-check ## Run a few checks before pushing a change (docs, fmt, mod, etc.) @@ -68,6 +68,9 @@ test: ## run unit and integration tests test-acceptance: ## run acceptance tests TF_ACC=1 go test -run "^TestAcc_" -v -cover -timeout=30m ./... +test-architecture: ## check architecture constraints between packages + go test ./pkg/architests/... -v + build-local: ## build the binary locally go build -o $(BASE_BINARY_NAME) .