Skip to content

Commit

Permalink
Generate re-usable functional test library
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanos committed Sep 19, 2024
1 parent aaa74a4 commit 9a1a9d0
Show file tree
Hide file tree
Showing 12 changed files with 3,025 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
tests/testlib/* linguist-generated=true
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ go-generate: $(MOCKGEN) $(GOIMPORTS) $(STRINGER)
@printf $(COLOR) "Process go:generate directives..."
@go generate ./...

gentestsuites:
@go run cmd/tools/gentestsuites/main.go tests/

ensure-no-changes:
@printf $(COLOR) "Check for local changes..."
@printf $(COLOR) "========================================================================"
Expand Down
180 changes: 180 additions & 0 deletions cmd/tools/gentestsuites/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// The MIT License
//
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
//
// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
)

var structRegex = regexp.MustCompile(`type\s+([A-Za-z0-9_]+Suite)\s+struct`)

const (
testFileSuffix = "_test.go"
genHeader = "// Code generated by `make gentestsuites`. DO NOT EDIT.\n\n"
outputDirName = "testlib"
outputFile = "suites_gen.go"
)

func main() {
if len(os.Args) != 2 {
log.Fatalf("Usage: gentestsuites <directory>")
}
path := os.Args[1]

srcDir, err := filepath.Abs(path)
if err != nil {
log.Fatalf("Error resolving file path: %v", err)
}
fmt.Printf("Scanning: %s\n", srcDir)

//pkgName := findPackageName(srcDir)

outDir := filepath.Join(srcDir, outputDirName)
os.Mkdir(outDir, 0777)
err = copyFiles(srcDir, outDir)

suites := findSuites(err, srcDir)
if len(suites) == 0 {
log.Fatalf("No suites found")
}
//generateSuitesFile(dir, pkgName, suites)
}

func copyFiles(srcDir, outDir string) error {
files, err := ioutil.ReadDir(srcDir)
if err != nil {
log.Fatalf("Error reading directory: %v\n", err)
}

for _, file := range files {
if file.IsDir() {
continue
}

srcFilePath := filepath.Join(srcDir, file.Name())
destFileName := strings.TrimSuffix(file.Name(), testFileSuffix) + ".go"
destFilePath := filepath.Join(outDir, destFileName)

err = copyFile(srcFilePath, destFilePath)
if err != nil {
log.Fatalf("Error copying file: %v\n", err)
}
fmt.Printf("Generated: %s\n", destFilePath)
}
return err
}

func copyFile(src, dst string) error {
srcFile, err := os.Open(src)
if err != nil {
return err
}
defer srcFile.Close()

destFile, err := os.Create(dst)
if err != nil {
return err
}
defer destFile.Close()

_, err = destFile.WriteString(genHeader)
if err != nil {
return err
}

_, err = io.Copy(destFile, srcFile)
return err
}

func findSuites(err error, dir string) []string {
var suites []string

files, err := ioutil.ReadDir(dir)
if err != nil {
log.Fatalf("Error reading directory: %v\n", err)
}

for _, file := range files {
if file.IsDir() || !strings.HasSuffix(file.Name(), testFileSuffix) {
continue
}

content, err := os.ReadFile(filepath.Join(dir, file.Name()))
if err != nil {
log.Fatalf("Error reading file:", file, err)
}

matches := structRegex.FindAllStringSubmatch(string(content), -1)
if matches != nil {
for _, match := range matches {
suite := match[1]
fmt.Printf("Found suite: %s\n", suite)
suites = append(suites, suite)
}
}
}

sort.Strings(suites)
return suites
}

func findPackageName(path string) string {
cmd := exec.Command("go", "list", path)
listOutput, err := cmd.Output()
if err != nil {
log.Fatalf("Error running go list: %v", err)
}
packagePaths := strings.Split(strings.TrimSpace(string(listOutput)), "/")
return packagePaths[len(packagePaths)-1]
}

func generateSuitesFile(dir, pkg string, suites []string) {
outputPath := filepath.Join(dir, outputFile)
f, err := os.Create(outputPath)
if err != nil {
log.Fatalf("Unable to create output file: %v", err)
}
defer f.Close()

fmt.Fprintf(f, genHeader)
fmt.Fprintf(f, "package "+pkg+"\n\n")
fmt.Fprintf(f, "import \"github.com/stretchr/testify/suite\"\n\n")
fmt.Fprintf(f, "var Suites = []suite.TestingSuite{\n")
for _, s := range suites {
fmt.Fprintf(f, "\tnew(%s),\n", s)
}
fmt.Fprintf(f, "}\n")

fmt.Printf("Generated: %s\n", outputPath)
}
Loading

0 comments on commit 9a1a9d0

Please sign in to comment.