github.com/ipld/go-ipld-prime@v0.21.0/schema/gen/go/testEngine_test.go (about)

     1  package gengo
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/ipld/go-ipld-prime/datamodel"
    10  	"github.com/ipld/go-ipld-prime/node/tests"
    11  	"github.com/ipld/go-ipld-prime/schema"
    12  )
    13  
    14  var _ tests.Engine = (*genAndCompileEngine)(nil)
    15  
    16  type genAndCompileEngine struct {
    17  	subtestName string
    18  	prefix      string
    19  
    20  	adjCfg AdjunctCfg
    21  
    22  	prototypeByName func(string) datamodel.NodePrototype
    23  }
    24  
    25  var tmpGenBuildDir = filepath.Join(os.TempDir(), "test-go-ipld-prime-gengo")
    26  
    27  func (e *genAndCompileEngine) Init(t *testing.T, ts schema.TypeSystem) {
    28  	// Make directories for the package we're about to generate.
    29  	// They will live in a temporary directory, usually
    30  	// /tmp/test-go-ipld-prime-gengo on Linux. It can be removed at any time.
    31  	// We don't by default because it's nicer to let go's builds of things cache.
    32  	// If you change the names of types, though, you'll have garbage files leftover,
    33  	// and that's currently a manual cleanup problem.  Sorry.
    34  	dir := filepath.Join(tmpGenBuildDir, e.prefix)
    35  	if err := os.MkdirAll(dir, 0755); err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	pkgName := "main"
    39  
    40  	// Generate... everything, really.
    41  	Generate(dir, pkgName, ts, &e.adjCfg)
    42  
    43  	// Emit an exported top level function for getting NodePrototype.
    44  	//  This part isn't necessary except for a special need we have with this plugin trick;
    45  	//   normally, user code uses the `{pkgname}.Prototype.{TypeName}` constant (so-to-speak, anyway) to get a hold of NodePrototypes...
    46  	//   but for plugins, we need a top-level exported symbol to grab ahold of, and we can't easily look through the `Prototype` value
    47  	//    without an interface... so we generate this function to fit the bill instead.
    48  	withFile(filepath.Join(dir, "prototypeGetter.go"), func(w io.Writer) {
    49  		doTemplate(`
    50  			package `+pkgName+`
    51  
    52  			import "github.com/ipld/go-ipld-prime/datamodel"
    53  
    54  			func GetPrototypeByName(name string) datamodel.NodePrototype {
    55  				switch name {
    56  				{{- range . }}
    57  				case "{{ .Name }}":
    58  					return _{{ . | TypeSymbol }}__Prototype{}
    59  				case "{{ .Name }}.Repr":
    60  					return _{{ . | TypeSymbol }}__ReprPrototype{}
    61  				{{- end}}
    62  				default:
    63  					return nil
    64  				}
    65  			}
    66  		`, w, &e.adjCfg, ts.GetTypes())
    67  	})
    68  
    69  	// Build the genned code.
    70  	//  This will either make a plugin (which we can run behavioral tests on next!),
    71  	//  or just build it quietly just to see if there are compile-time errors,
    72  	//  depending on your build tags.
    73  	// See 'HACKME_testing.md' for discussion.
    74  	buildGennedCode(t, e.prefix, pkgName)
    75  
    76  	e.prototypeByName = fnPrototypeByName(e.prefix)
    77  }
    78  
    79  func (e *genAndCompileEngine) PrototypeByName(name string) datamodel.NodePrototype {
    80  	return e.prototypeByName(name)
    81  }