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 }