Files
go-omni/cmd/go-omni/api_test.go

150 lines
4.6 KiB
Go

package main
import (
"encoding/json"
"io"
"os"
"path/filepath"
"strings"
"testing"
)
func TestAPICommands(t *testing.T) {
root, err := filepath.Abs("../..")
if err != nil {
t.Fatal(err)
}
project := filepath.Join(t.TempDir(), "demo")
if err = runAPI([]string{"new", project, "--module=example.com/demo", "--framework-dir", root}); err != nil {
t.Fatal(err)
}
api := filepath.Join(project, "api/service.api")
if err = runAPI([]string{"validate", "-api", api}); err != nil {
t.Fatal(err)
}
if err = runAPI([]string{"go", "-api", api, "-dir", project, "--check"}); err != nil {
t.Fatal(err)
}
if err = runNew([]string{"--force", project}); err == nil {
t.Fatal("CRUD starter overwrote API project")
}
target := filepath.Join(t.TempDir(), "other")
if err = runNew([]string{"--api", api, "--module", "example.com/other", "--framework-dir", root, target}); err != nil {
t.Fatal(err)
}
if _, err = os.Stat(filepath.Join(target, "internal/logic/greet/greet.go")); err != nil {
t.Fatal(err)
}
for _, args := range [][]string{{"validate"}, {"generate", "--api"}, {"new", "--api=x", "somewhere"}, {"generate", "--dir="}, {"generate", "--force"}, {"validate", "--api", api, "--dir", project}, {"validate", "--check"}} {
if err = runAPI(args); err == nil {
t.Fatalf("invalid args accepted: %v", args)
}
}
if err = runNew([]string{"--api", api, "--force", target}); err == nil || !strings.Contains(err.Error(), "do not accept --force") {
t.Fatalf("incompatible profile: %v", err)
}
}
func TestAPIDeveloperCommands(t *testing.T) {
root, err := filepath.Abs("../..")
if err != nil {
t.Fatal(err)
}
dir := filepath.Join(t.TempDir(), "project")
if err = runAPI([]string{"new", dir, "--framework-dir", root, "--module", "example.com/commands"}); err != nil {
t.Fatal(err)
}
// Generation can resolve the entry from an explicit target directory.
if err = runAPI([]string{"generate", "--dir", dir, "--dry-run"}); err != nil {
t.Fatal(err)
}
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if err = os.Chdir(dir); err != nil {
t.Fatal(err)
}
defer os.Chdir(wd)
for _, args := range [][]string{{"validate"}, {"inspect"}, {"generate", "--check"}} {
if err = runAPI(args); err != nil {
t.Fatalf("%v: %v", args, err)
}
}
doc := captureAPIOutput(t, []string{"export"})
var parsed map[string]any
if err = json.Unmarshal([]byte(doc), &parsed); err != nil {
t.Fatalf("export must be pure JSON: %v", err)
}
if parsed["openapi"] != "3.0.3" {
t.Fatal("wrong export")
}
for _, args := range [][]string{{"generate", "--dry-run", "--check"}, {"new", "--dry-run", "other"}, {"inspect", "--dir", dir}, {"export", "--log-output", "file"}} {
if err = runAPI(args); err == nil {
t.Fatalf("accepted invalid flags: %v", args)
}
}
}
func captureAPIOutput(t *testing.T, args []string) string {
t.Helper()
data, err := captureAPIResult(t, args)
if err != nil {
t.Fatal(err)
}
return data
}
func captureAPIResult(t *testing.T, args []string) (string, error) {
t.Helper()
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
previous := os.Stdout
os.Stdout = w
defer func() { os.Stdout = previous; r.Close(); w.Close() }()
result := make(chan []byte, 1)
go func() { data, _ := io.ReadAll(r); result <- data }()
callErr := runAPI(args)
w.Close()
os.Stdout = previous
data := <-result
return string(data), callErr
}
func TestAPIChangeDiagnosticsVisibleOnFailure(t *testing.T) {
root, err := filepath.Abs("../..")
if err != nil {
t.Fatal(err)
}
dir := filepath.Join(t.TempDir(), "app")
captureAPIOutput(t, []string{"new", dir, "--module", "example.com/diagnostics", "--framework-dir", root})
api := filepath.Join(dir, "api/service.api")
data, err := os.ReadFile(api)
if err != nil {
t.Fatal(err)
}
if err = os.WriteFile(api, []byte(strings.ReplaceAll(string(data), "GreetReq", "HelloReq")), 0644); err != nil {
t.Fatal(err)
}
for _, flag := range []string{"--dry-run", "--check", ""} {
args := []string{"generate", "--dir", dir}
if flag != "" {
args = append(args, flag)
}
text, err := captureAPIResult(t, args)
if (flag == "--check") != (err != nil) {
t.Fatalf("%s: %v", flag, err)
}
for _, want := range []string{"REVIEW [contractChanged]", "ERROR [logicSignature]", "internal/logic/greet/greet.go:", "types.HelloReq", "types.GreetReq"} {
if !strings.Contains(text, want) {
t.Fatalf("%s hides %q:\n%s", flag, want, text)
}
}
}
text, err := captureAPIResult(t, []string{"generate", "--dir", dir, "--check"})
if err == nil || !strings.Contains(text, "ERROR [logicSignature]") || strings.Contains(text, "files are current") {
t.Fatalf("check claimed success: %v\n%s", err, text)
}
}