119 lines
4.8 KiB
Go
119 lines
4.8 KiB
Go
package apigen
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func runConsumerGo(t *testing.T, dir string, args ...string) {
|
|
t.Helper()
|
|
ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second)
|
|
defer cancel()
|
|
cmd := exec.CommandContext(ctx, "go", args...)
|
|
cmd.Dir = dir
|
|
cmd.Env = append(os.Environ(), "GOWORK=off")
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
t.Fatalf("go %v: %v\n%s", args, err, out)
|
|
}
|
|
}
|
|
func TestCopyxThreeEndpointConsumer(t *testing.T) {
|
|
if os.Getenv("GO_OMNI_SCAFFOLD_INTEGRATION") != "1" {
|
|
t.Skip("set GO_OMNI_SCAFFOLD_INTEGRATION=1")
|
|
}
|
|
dir := filepath.Join(t.TempDir(), "app")
|
|
o := Options{API: filepath.Join(frameworkRoot(t), "cmd/go-omni/apigen/testdata/composition/service.api"), Dir: dir, Module: "example.com/composition", FrameworkDir: frameworkRoot(t)}
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for path, fixture := range map[string]string{
|
|
"internal/amount/money.go": "amount.go", "internal/domain/employee.go": "domain.go", "internal/convert/fields.go": "converters.go", "internal/convert/copy.go": "copy.go",
|
|
"internal/middleware/dependencies.go": "dependencies.go", "internal/middleware/accessFactory.go": "accessFactory.go", "internal/svc/client.go": "client.go", "consumer_test.go": "consumer_test.go",
|
|
} {
|
|
writeFile(t, filepath.Join(dir, path), readFile(t, "testdata/composition/"+fixture))
|
|
}
|
|
svcFile := filepath.Join(dir, "internal/svc/serviceContext.go")
|
|
source := strings.Replace(readFile(t, svcFile), "type ServiceContext struct {", "type ServiceContext struct {\n client *Client", 1)
|
|
source = strings.Replace(source, "return nil", "return c.initClient(ctx)", 1)
|
|
writeFile(t, svcFile, source)
|
|
configFile := filepath.Join(dir, "internal/config/config.go")
|
|
writeFile(t, configFile, strings.Replace(readFile(t, configFile), "type Config struct {", "type Config struct {\n FactoryMode string `json:\"factoryMode\"`", 1))
|
|
for _, group := range []string{"Enterprise", "Tenant", "Admin"} {
|
|
text := fmt.Sprintf(`package %s
|
|
import("context";"example.com/composition/internal/types";"example.com/composition/internal/convert";"example.com/composition/internal/domain")
|
|
func(s *Logic)Save(ctx context.Context,req *types.%sRequest)(*types.EmployeeResponse,error){
|
|
input,err:=convert.Employee(*req);if err!=nil{return nil,err}
|
|
result,err:=convert.Response(domain.Result{Employee:input,ID:9007199254740993});if err!=nil{return nil,err};return &result,nil
|
|
}
|
|
`, strings.ToLower(group), group)
|
|
writeFile(t, filepath.Join(dir, "internal/logic", strings.ToLower(group), "save.go"), text)
|
|
}
|
|
runConsumerGo(t, dir, "mod", "tidy")
|
|
runConsumerGo(t, dir, "test", "-race", "-count=1", "./...")
|
|
o.API = filepath.Join(dir, "api/service.api")
|
|
before := snapshot(t, dir)
|
|
o.DryRun = true
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
o.DryRun = false
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
o.Check = true
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("generation changed business files")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "internal/mapping")); !os.IsNotExist(err) {
|
|
t.Fatal("mapping directory generated")
|
|
}
|
|
// Adding a common field requires one contract edit and one independent
|
|
// business field. Three endpoint converters need no new rules.
|
|
contract := readFile(t, o.API)
|
|
contract = strings.Replace(contract, "type SalaryFields {", "type SalaryFields {\n Note string `json:\"note,optional\"`", 1)
|
|
writeFile(t, o.API, contract)
|
|
domainPath := filepath.Join(dir, "internal/domain/employee.go")
|
|
writeFile(t, domainPath, strings.Replace(readFile(t, domainPath), "type Employee struct {", "type Employee struct {\n Note string", 1))
|
|
o.Check = false
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
o.Check = true
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
runConsumerGo(t, dir, "test", "-race", "-count=1", "./...")
|
|
runConsumerGo(t, dir, "build", ".")
|
|
if os.Getenv("GO_OMNI_RELEASE_CLI") != "" {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
cmd := exec.CommandContext(ctx, "go", "list", "-m", "-json", frameworkModule)
|
|
cmd.Dir = dir
|
|
cmd.Env = append(os.Environ(), "GOWORK=off")
|
|
data, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatal(err, string(data))
|
|
}
|
|
var dependency struct {
|
|
Version, Sum string
|
|
Replace any
|
|
}
|
|
if err = json.Unmarshal(data, &dependency); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if dependency.Version != os.Getenv("GO_OMNI_RELEASE_VERSION") || dependency.Replace != nil || dependency.Sum == "" {
|
|
t.Fatal("not a fixed remote consumer")
|
|
}
|
|
t.Logf("remote framework %s checksum %s; no local replace", dependency.Version, dependency.Sum)
|
|
}
|
|
}
|