github.com/alkemics/goflow@v0.2.1/gfutil/gfgo/testutil.go (about)

     1  package gfgo
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"path"
     9  	"strings"
    10  	"testing"
    11  	"text/template"
    12  
    13  	"github.com/alkemics/goflow"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  const mainTmpl = `
    19  // Code generated by lib-go/goflow DO NOT EDIT.
    20  
    21  // +build !codeanalysis
    22  
    23  package main
    24  
    25  import (
    26  	"fmt"
    27  	{{ range .Imports }}
    28  	"{{ . }}"
    29  	{{ end }}
    30  )
    31  
    32  func assert(b bool) {
    33  	if !b {
    34  		panic("assertion failed")
    35  	}
    36  }
    37  
    38  func main() {
    39  	var g {{ .Name }}
    40  	{{ range .Tests }}
    41  	g = New{{ $.Name }}({{ .Deps }})
    42  	{{ .Test }}
    43  	fmt.Println("Test done.")
    44  	{{ end }}
    45  	fmt.Println("All tests done.")
    46  }
    47  `
    48  
    49  type TestCases struct {
    50  	Imports []string
    51  	Tests   []TestCase
    52  }
    53  
    54  type TestCase struct {
    55  	Deps string
    56  	Test string
    57  }
    58  
    59  // TestGenerate should be used to simplify testing the wrappers.
    60  //
    61  // Each element of testCases should be valid go code. The graph
    62  // created is called g.
    63  func TestGenerate(t *testing.T, wrappers []goflow.GraphWrapper, filename string, testCases TestCases) {
    64  	require := require.New(t)
    65  
    66  	graph, err := goflow.Load(filename, wrappers)
    67  	require.NoError(err)
    68  
    69  	goFilename := path.Join("graph", strings.ReplaceAll(filename, ".yml", ".go"))
    70  	buf := bytes.Buffer{}
    71  	w := NewWriter(
    72  		&buf,
    73  		goFilename,
    74  	)
    75  	err = Generate(w, graph)
    76  	require.NoError(err)
    77  	require.NoError(w.Flush())
    78  
    79  	if _, err := os.Open("graph"); os.IsNotExist(err) {
    80  		require.NoError(os.Mkdir("graph", 0o755))
    81  	} else if err != nil {
    82  		require.NoError(err)
    83  	}
    84  	err = ioutil.WriteFile(goFilename, buf.Bytes(), 0o600)
    85  	require.NoError(err)
    86  
    87  	mainFilename := path.Join("graph", "main.go")
    88  	tmpl, err := template.New("main").Parse(mainTmpl)
    89  	require.NoError(err)
    90  
    91  	if len(testCases.Tests) == 0 {
    92  		testCases = TestCases{
    93  			Tests: []TestCase{
    94  				{
    95  					Deps: "",
    96  					Test: "g.Run()",
    97  				},
    98  			},
    99  		}
   100  	}
   101  
   102  	buf = bytes.Buffer{}
   103  	w = NewWriter(
   104  		&buf,
   105  		mainFilename,
   106  	)
   107  	err = tmpl.Execute(w, struct {
   108  		Name    string
   109  		Imports []string
   110  		Tests   []TestCase
   111  	}{
   112  		Name:    graph.Name(),
   113  		Imports: testCases.Imports,
   114  		Tests:   testCases.Tests,
   115  	})
   116  	require.NoError(err)
   117  	require.NoError(w.Flush())
   118  
   119  	require.NoError(err)
   120  	require.NoError(ioutil.WriteFile(mainFilename, buf.Bytes(), 0o600))
   121  
   122  	cmd := exec.Command("go", "run", "./graph")
   123  	var out, errOut bytes.Buffer
   124  	cmd.Stdout = &out
   125  	cmd.Stderr = &errOut
   126  	if !assert.NoError(t, cmd.Run()) {
   127  		t.Log(errOut.String())
   128  	}
   129  	t.Logf("Graph output:\n%s", out.String())
   130  }
   131  
   132  func TestLint(t *testing.T, linters []goflow.Linter, filename string) error {
   133  	wrappers := make([]goflow.GraphWrapper, len(linters))
   134  	for i, linter := range linters {
   135  		wrappers[i] = goflow.FromLinter(linter)
   136  	}
   137  
   138  	_, err := goflow.Load(filename, wrappers)
   139  	return err
   140  }
   141  
   142  func TestCheck(t *testing.T, wrappers []goflow.GraphWrapper, checkers []goflow.Checker, filename string) error {
   143  	for _, checker := range checkers {
   144  		wrappers = append(wrappers, goflow.FromChecker(checker))
   145  	}
   146  
   147  	_, err := goflow.Load(filename, wrappers)
   148  	return err
   149  }