From 153b785a477ce7416a3183d21b6b12de7a0f9f70 Mon Sep 17 00:00:00 2001 From: Matthew Nibecker Date: Mon, 1 Apr 2024 12:08:02 -0700 Subject: [PATCH] Test Go Library Examples Add markdown test to run go vet on go library examples. Fix existing go library examples. Closes #4703 --- docs/libraries/go.md | 12 ++++++------ mdtest/mdtest.go | 5 +++++ mdtest/test.go | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/libraries/go.md b/docs/libraries/go.md index 3b9dbf55e9..4f0dbb10ba 100644 --- a/docs/libraries/go.md +++ b/docs/libraries/go.md @@ -39,7 +39,7 @@ go get github.com/brimdata/zed ### ZSON Reader Read ZSON from stdin, dereference field `s`, and print results: -``` +```mdtest-go-example package main import ( @@ -54,7 +54,7 @@ import ( func main() { zctx := zed.NewContext() - reader := zsonio.NewReader(os.Stdin, zctx) + reader := zsonio.NewReader(zctx, os.Stdin) for { val, err := reader.Read() if err != nil { @@ -65,7 +65,7 @@ func main() { } s := val.Deref("s") if s == nil { - s = zctx.Missing() + s = zctx.Missing().Ptr() } fmt.Println(zson.String(s)) } @@ -105,7 +105,7 @@ zed create -lake scratch Demo echo '{s:"hello, world"}{x:1}{s:"good bye"}' | zed load -lake scratch -use Demo - ``` Now replace `main.go` with this code: -``` +```mdtest-go-example package main import ( @@ -129,7 +129,7 @@ func main() { log.Fatalln(err) } ctx := context.TODO() - lake, err := api.OpenLake(ctx, uri.String()) + lake, err := api.OpenLake(ctx, nil, uri.String()) if err != nil { log.Fatalln(err) } @@ -149,7 +149,7 @@ func main() { } s := val.Deref("s") if s == nil { - s = zctx.Missing() + s = zctx.Missing().Ptr() } fmt.Println(zson.String(s)) } diff --git a/mdtest/mdtest.go b/mdtest/mdtest.go index a6a9679138..c8dc842ceb 100644 --- a/mdtest/mdtest.go +++ b/mdtest/mdtest.go @@ -192,6 +192,11 @@ func parseMarkdown(source []byte) (map[string]string, []*Test, error) { Line: fcbLineNumber(commandFCB, source), }) commandFCB = nil + case "mdtest-go-example": + tests = append(tests, &Test{ + GoExample: fcbLines(fcb, source), + Line: fcbLineNumber(fcb, source), + }) } return ast.WalkContinue, nil }) diff --git a/mdtest/test.go b/mdtest/test.go index 07eb489b90..35e58b9ac6 100644 --- a/mdtest/test.go +++ b/mdtest/test.go @@ -3,7 +3,9 @@ package mdtest import ( "errors" "fmt" + "os" "os/exec" + "path/filepath" "strings" "github.com/pmezard/go-difflib/difflib" @@ -11,16 +13,20 @@ import ( // Test represents a single test in a Markdown file. type Test struct { - Command string - Dir string - Expected string - Fails bool - Head bool - Line int + Command string + Dir string + Expected string + Fails bool + Head bool + Line int + GoExample string } // Run runs the test, returning nil on success. func (t *Test) Run() error { + if t.GoExample != "" { + return t.vetGoExample() + } c := exec.Command("bash", "-e", "-o", "pipefail") c.Dir = t.Dir c.Stdin = strings.NewReader(t.Command) @@ -57,3 +63,21 @@ func (t *Test) Run() error { } return nil } + +func (t *Test) vetGoExample() error { + dir, err := os.MkdirTemp("", "") + if err != nil { + return err + } + defer os.RemoveAll(dir) + path := filepath.Join(dir, "main.go") + if err := os.WriteFile(path, []byte(t.GoExample), 0666); err != nil { + return err + } + _, err = exec.Command("go", "vet", path).Output() + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + return fmt.Errorf("could not vet go example: %s", string(exitErr.Stderr)) + } + return err +}