From f09110484353cd289fe0e24a492d2f70c477a68b Mon Sep 17 00:00:00 2001 From: Jolyon Direnko-Smith Date: Tue, 28 May 2024 13:56:40 +1200 Subject: [PATCH] fix(options): --verbose option now works as intended (closes #11) --- .gitignore | 2 +- README.md | 6 ++- internal/coalesce.go | 11 ++++++ internal/coalesce_test.go | 48 ++++++++++++++++++++++++ internal/opts.go | 55 ++++++++++------------------ internal/opts_test.go | 16 ++++++++ internal/parser.go | 18 ++++++--- internal/parser_test.go | 30 +++++++++++++++ internal/testdata/no-code.json | 1 - internal/testdata/no-test-files.json | 3 -- internal/testdata/packages.json | 54 --------------------------- 11 files changed, 142 insertions(+), 102 deletions(-) create mode 100644 internal/coalesce.go create mode 100644 internal/coalesce_test.go delete mode 100644 internal/testdata/no-code.json delete mode 100644 internal/testdata/no-test-files.json delete mode 100644 internal/testdata/packages.json diff --git a/.gitignore b/.gitignore index d13f471..b2a574e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,6 @@ dist/** test-report # test data (generated when parser_test.go is run) -testdata/*.json +**/testdata/*.json # any test/sample report (md) in the root test-report.md diff --git a/README.md b/README.md index 2ec2a1d..78cece3 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,13 @@ Options: -o, --output the output filename (default "test-report.md") + -s, --summary produce a summary report only (no details of failed tests) + -t, --title the title text shown in the test report (default "Test Report") -h, --help help for test-report - -v, --verbose while processing, show the complete output from go test + -v, --verbose while processing, show the (JSON) output from go test ``` The name of the output file can be changed by using the `-o` or `--output` option. @@ -168,7 +170,7 @@ The report details section might appear similar to: ## Background -This tool was created to satisfy a desire to incorporate a test report into github +This tool was created to satisfy a desire to incorporate a test report into Github action job summaries, for which the HTML produced by existing tools was not suitable. Markdown seemed to offer a better fit for that use case, and so this tool was born. diff --git a/internal/coalesce.go b/internal/coalesce.go new file mode 100644 index 0000000..67f2bd2 --- /dev/null +++ b/internal/coalesce.go @@ -0,0 +1,11 @@ +package internal + +func coalesce[T comparable](values ...T) T { + z := *new(T) + for _, v := range values { + if v != z { + return v + } + } + return z +} diff --git a/internal/coalesce_test.go b/internal/coalesce_test.go new file mode 100644 index 0000000..5ea8e48 --- /dev/null +++ b/internal/coalesce_test.go @@ -0,0 +1,48 @@ +package internal + +import ( + "testing" + + "github.com/blugnu/test" +) + +func TestCoalesce(t *testing.T) { + // ARRANGE + testcases := []struct { + scenario string + exec func(t *testing.T) + }{ + {scenario: "(z,nz)", + exec: func(t *testing.T) { + // ACT + result := coalesce(0, 1) + + // ASSERT + test.That(t, result).Equals(1) + }, + }, + {scenario: "(nz,nz)", + exec: func(t *testing.T) { + // ACT + result := coalesce(1, 2) + + // ASSERT + test.That(t, result).Equals(1) + }, + }, + {scenario: "no args", + exec: func(t *testing.T) { + // ACT + result := coalesce[int]() + + // ASSERT + test.That(t, result).Equals(0) + }, + }, + } + for _, tc := range testcases { + t.Run(tc.scenario, func(t *testing.T) { + tc.exec(t) + }) + } +} diff --git a/internal/opts.go b/internal/opts.go index 3486574..f7f71a4 100644 --- a/internal/opts.go +++ b/internal/opts.go @@ -17,20 +17,14 @@ type Options struct{} // parse is a method that parses the command line arguments and returns the // appropriate command to run (if any). func (o *Options) Parse() (interface{ Run(*Options) int }, error) { - var ( - of string = "test-report.md" - rm reportMode = rmFailedTests - rt string = "Test Report" - - opts = struct { - h, help bool - f, full bool - o, output string - s, summary bool - t, title string - }{} - ) - + opts := struct { + h, help bool + f, full bool + o, output string + s, summary bool + t, title string + v, verbose bool + }{} if len(os.Args) > 1 { if os.Args[1] == "version" { return showVersion{}, nil @@ -47,30 +41,21 @@ func (o *Options) Parse() (interface{ Run(*Options) int }, error) { flags.BoolVar(&opts.summary, "summary", false, "") flags.StringVar(&opts.t, "t", "", "report title") flags.StringVar(&opts.title, "title", "", "") + flags.BoolVar(&opts.v, "v", false, "verbose output") + flags.BoolVar(&opts.verbose, "verbose", false, "") if err := ParseFlags(flags, os.Args[1:]); err != nil { return nil, err } + } + of := coalesce(opts.o, opts.output, "test-report.md") + rt := coalesce(opts.t, opts.title, "Test Report") - switch { - case opts.o != "": - of = opts.o - case opts.output != "": - of = opts.output - } - - switch { - case opts.t != "": - rt = opts.t - case opts.title != "": - rt = opts.title - } - - switch { - case opts.f || opts.full: - rm = rmAllTests - case opts.s || opts.summary: - rm = rmSummaryOnly - } + rm := rmFailedTests + if opts.f || opts.full { + rm = rmAllTests + } + if opts.s || opts.summary { + rm = rmSummaryOnly } switch { @@ -82,7 +67,7 @@ func (o *Options) Parse() (interface{ Run(*Options) int }, error) { filename: of, title: rt, mode: rm, - parser: &parser{}, + parser: &parser{verbose: opts.v || opts.verbose}, }, nil } } diff --git a/internal/opts_test.go b/internal/opts_test.go index 773354a..1482db4 100644 --- a/internal/opts_test.go +++ b/internal/opts_test.go @@ -116,6 +116,22 @@ func TestOpts(t *testing.T) { parser: &parser{}, }, }, + {args: []string{"-v"}, + result: generateReport{ + filename: "test-report.md", + title: "Test Report", + mode: rmFailedTests, + parser: &parser{verbose: true}, + }, + }, + {args: []string{"--verbose"}, + result: generateReport{ + filename: "test-report.md", + title: "Test Report", + mode: rmFailedTests, + parser: &parser{verbose: true}, + }, + }, } for _, tc := range testcases { t.Run(fmt.Sprintf("%s", tc.args), func(t *testing.T) { diff --git a/internal/parser.go b/internal/parser.go index bcbc52a..b0e974e 100644 --- a/internal/parser.go +++ b/internal/parser.go @@ -5,15 +5,16 @@ import ( "fmt" "io" "math" + "os" "regexp" "strings" "time" ) type line struct { - Time string `json:"Time"` + Time string `json:"Time,omitempty"` Action string `json:"Action"` - Package string `json:"Package"` + Package string `json:"Package,omitempty"` Test *string `json:"Test,omitempty"` Elapsed *float64 `json:"Elapsed,omitempty"` Output *string `json:"Output,omitempty"` @@ -24,9 +25,10 @@ func (line line) elapsedDur() time.Duration { } type parser struct { - pkgs map[string]*packageinfo - tests map[string]map[string]*testinfo - srcref *regexp.Regexp + pkgs map[string]*packageinfo + tests map[string]map[string]*testinfo + srcref *regexp.Regexp + verbose bool } func (p *parser) parse(r io.Reader, rpt *testrun) error { @@ -35,6 +37,10 @@ func (p *parser) parse(r io.Reader, rpt *testrun) error { p.srcref, _ = regexp.Compile(`(.*\.go:[0-9]*): (.*)\n`) *rpt = testrun{} + echo := func([]byte) (int, error) { return 0, nil } + if p.verbose { + echo = os.Stdout.Write + } decoder := json.NewDecoder(r) for { @@ -44,7 +50,7 @@ func (p *parser) parse(r io.Reader, rpt *testrun) error { } s, _ := json.Marshal(l) - fmt.Println(string(s)) + _, _ = echo(s) if l.Test == nil && l.Elapsed != nil { rpt.elapsed = l.elapsedDur() diff --git a/internal/parser_test.go b/internal/parser_test.go index a3a7a04..56867c2 100644 --- a/internal/parser_test.go +++ b/internal/parser_test.go @@ -108,6 +108,36 @@ func TestParse(t *testing.T) { test.That(t, report.numSkipped).Equals(0, "tests skipped") }, }, + {scenario: "verbose==true", + exec: func(t *testing.T) { + report := &testrun{} + input := bytes.NewReader([]byte(`{"Action":"output"}`)) + p := parser{verbose: true} + + // ACT + stdout, _ := test.CaptureOutput(t, func() { + _ = p.parse(input, report) + }) + + // ASSERT + stdout.Equals([]string{`{"Action":"output"}`}) + }, + }, + {scenario: "verbose==false", + exec: func(t *testing.T) { + report := &testrun{} + input := bytes.NewReader([]byte(`{"Action":"output"}`)) + p := parser{verbose: false} + + // ACT + stdout, _ := test.CaptureOutput(t, func() { + _ = p.parse(input, report) + }) + + // ASSERT + stdout.IsEmpty() + }, + }, } for _, tc := range testcases { t.Run(tc.scenario, func(t *testing.T) { diff --git a/internal/testdata/no-code.json b/internal/testdata/no-code.json deleted file mode 100644 index 3cf3ae1..0000000 --- a/internal/testdata/no-code.json +++ /dev/null @@ -1 +0,0 @@ -no Go files in /Volumes/Cloud/Dropbox/dev/github/blugnu/work/kafka-client/test-report/internal/testdata/no-code diff --git a/internal/testdata/no-test-files.json b/internal/testdata/no-test-files.json deleted file mode 100644 index 5e63508..0000000 --- a/internal/testdata/no-test-files.json +++ /dev/null @@ -1,3 +0,0 @@ -{"Time":"2024-05-28T10:04:04.139873+12:00","Action":"start","Package":"github.com/blugnu/test-report/internal/testdata/no-test-files"} -{"Time":"2024-05-28T10:04:04.140571+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/no-test-files","Output":"? \tgithub.com/blugnu/test-report/internal/testdata/no-test-files\t[no test files]\n"} -{"Time":"2024-05-28T10:04:04.140617+12:00","Action":"skip","Package":"github.com/blugnu/test-report/internal/testdata/no-test-files","Elapsed":0.001} diff --git a/internal/testdata/packages.json b/internal/testdata/packages.json deleted file mode 100644 index aad9508..0000000 --- a/internal/testdata/packages.json +++ /dev/null @@ -1,54 +0,0 @@ -{"Time":"2024-05-28T10:04:03.767432+12:00","Action":"start","Package":"github.com/blugnu/test-report/internal/testdata/pkga"} -{"Time":"2024-05-28T10:04:03.767524+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Test":"TestPasses"} -{"Time":"2024-05-28T10:04:03.767528+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Test":"TestPasses","Output":"=== RUN TestPasses\n"} -{"Time":"2024-05-28T10:04:03.76754+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Test":"TestPasses","Output":"--- PASS: TestPasses (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.767543+12:00","Action":"pass","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Test":"TestPasses","Elapsed":0} -{"Time":"2024-05-28T10:04:03.767553+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Output":"PASS\n"} -{"Time":"2024-05-28T10:04:03.767558+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Output":"ok \tgithub.com/blugnu/test-report/internal/testdata/pkga\t(cached)\n"} -{"Time":"2024-05-28T10:04:03.767569+12:00","Action":"pass","Package":"github.com/blugnu/test-report/internal/testdata/pkga","Elapsed":0} -{"Time":"2024-05-28T10:04:03.841716+12:00","Action":"start","Package":"github.com/blugnu/test-report/internal/testdata/pkgb"} -{"Time":"2024-05-28T10:04:03.965677+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestPasses"} -{"Time":"2024-05-28T10:04:03.965712+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestPasses","Output":"=== RUN TestPasses\n"} -{"Time":"2024-05-28T10:04:03.96609+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestPasses","Output":"--- PASS: TestPasses (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966097+12:00","Action":"pass","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestPasses","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966106+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails"} -{"Time":"2024-05-28T10:04:03.966109+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":"=== RUN TestFails\n"} -{"Time":"2024-05-28T10:04:03.966112+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":" pkgb_test.go:11: this test fails\n"} -{"Time":"2024-05-28T10:04:03.966119+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":" with four\n"} -{"Time":"2024-05-28T10:04:03.966131+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":" lines of output\n"} -{"Time":"2024-05-28T10:04:03.966133+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":" the last is indented\n"} -{"Time":"2024-05-28T10:04:03.966149+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":"raw output is not indented (unlike test failure output)"} -{"Time":"2024-05-28T10:04:03.966163+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Output":"--- FAIL: TestFails (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966167+12:00","Action":"fail","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestFails","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966171+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSkipped"} -{"Time":"2024-05-28T10:04:03.966183+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSkipped","Output":"=== RUN TestSkipped\n"} -{"Time":"2024-05-28T10:04:03.966185+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSkipped","Output":" pkgb_test.go:16: this test is skipped\n"} -{"Time":"2024-05-28T10:04:03.966188+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSkipped","Output":"--- SKIP: TestSkipped (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966191+12:00","Action":"skip","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSkipped","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966194+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest"} -{"Time":"2024-05-28T10:04:03.966196+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest","Output":"=== RUN TestSubtest\n"} -{"Time":"2024-05-28T10:04:03.9662+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest"} -{"Time":"2024-05-28T10:04:03.966202+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest","Output":"=== RUN TestSubtest/subtest\n"} -{"Time":"2024-05-28T10:04:03.966208+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/fails"} -{"Time":"2024-05-28T10:04:03.966211+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/fails","Output":"=== RUN TestSubtest/subtest/fails\n"} -{"Time":"2024-05-28T10:04:03.966214+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/fails","Output":" pkgb_test.go:22: this test fails\n"} -{"Time":"2024-05-28T10:04:03.966217+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/fails","Output":"--- FAIL: TestSubtest/subtest/fails (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.96622+12:00","Action":"fail","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/fails","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966223+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes"} -{"Time":"2024-05-28T10:04:03.966225+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes","Output":"=== RUN TestSubtest/subtest/passes\n"} -{"Time":"2024-05-28T10:04:03.966227+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes","Output":" pkgb_test.go:26: this test passes\n"} -{"Time":"2024-05-28T10:04:03.96623+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes","Output":" pkgb_test.go:27: with two lines of output\n"} -{"Time":"2024-05-28T10:04:03.966234+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes","Output":"--- PASS: TestSubtest/subtest/passes (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966236+12:00","Action":"pass","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/passes","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966239+12:00","Action":"run","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/skipped"} -{"Time":"2024-05-28T10:04:03.966244+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/skipped","Output":"=== RUN TestSubtest/subtest/skipped\n"} -{"Time":"2024-05-28T10:04:03.966247+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/skipped","Output":" pkgb_test.go:31: this test is skipped\n"} -{"Time":"2024-05-28T10:04:03.96625+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/skipped","Output":"--- SKIP: TestSubtest/subtest/skipped (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966253+12:00","Action":"skip","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest/skipped","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966259+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest","Output":"--- FAIL: TestSubtest/subtest (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966262+12:00","Action":"fail","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest/subtest","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966264+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest","Output":"--- FAIL: TestSubtest (0.00s)\n"} -{"Time":"2024-05-28T10:04:03.966267+12:00","Action":"fail","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Test":"TestSubtest","Elapsed":0} -{"Time":"2024-05-28T10:04:03.966269+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Output":"FAIL\n"} -{"Time":"2024-05-28T10:04:03.966437+12:00","Action":"output","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Output":"FAIL\tgithub.com/blugnu/test-report/internal/testdata/pkgb\t0.125s\n"} -{"Time":"2024-05-28T10:04:03.966451+12:00","Action":"fail","Package":"github.com/blugnu/test-report/internal/testdata/pkgb","Elapsed":0.125}