gotest.tools/gotestsum@v1.11.0/cmd/handler_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "gotest.tools/gotestsum/internal/junitxml" 12 "gotest.tools/gotestsum/internal/text" 13 "gotest.tools/gotestsum/testjson" 14 "gotest.tools/v3/assert" 15 "gotest.tools/v3/assert/cmp" 16 "gotest.tools/v3/env" 17 "gotest.tools/v3/fs" 18 "gotest.tools/v3/golden" 19 ) 20 21 func TestPostRunHook(t *testing.T) { 22 command := &commandValue{} 23 err := command.Set("go run ./testdata/postrunhook/main.go") 24 assert.NilError(t, err) 25 26 buf := new(bytes.Buffer) 27 opts := &options{ 28 postRunHookCmd: command, 29 jsonFile: "events.json", 30 jsonFileTimingEvents: "timing.json", 31 junitFile: "junit.xml", 32 stdout: buf, 33 } 34 35 env.Patch(t, "GOTESTSUM_FORMAT", "short") 36 37 exec := newExecFromTestData(t) 38 err = postRunHook(opts, exec) 39 assert.NilError(t, err) 40 41 actual := text.ProcessLines(t, buf, func(line string) string { 42 if strings.HasPrefix(line, "GOTESTSUM_ELAPSED=0.0") && 43 strings.HasSuffix(line, "s") { 44 i := strings.Index(line, "=") 45 return line[:i] + "=0.000s" 46 } 47 return line 48 }) 49 golden.Assert(t, actual, "post-run-hook-expected") 50 } 51 52 func newExecFromTestData(t *testing.T) *testjson.Execution { 53 t.Helper() 54 f, err := os.Open("../testjson/testdata/input/go-test-json.out") 55 assert.NilError(t, err) 56 defer f.Close() // nolint: errcheck 57 58 exec, err := testjson.ScanTestOutput(testjson.ScanConfig{ 59 Stdout: f, 60 Stderr: strings.NewReader(""), 61 }) 62 assert.NilError(t, err) 63 return exec 64 } 65 66 type bufferCloser struct { 67 bytes.Buffer 68 } 69 70 func (bufferCloser) Close() error { return nil } 71 72 func (bufferCloser) Sync() error { return nil } 73 74 func TestEventHandler_Event_WithMissingActionFail(t *testing.T) { 75 t.Setenv("GITHUB_ACTIONS", "no") 76 77 buf := new(bufferCloser) 78 errBuf := new(bytes.Buffer) 79 format := testjson.NewEventFormatter(errBuf, "testname", testjson.FormatOptions{}) 80 81 source := golden.Get(t, "../../testjson/testdata/input/go-test-json-missing-test-fail.out") 82 cfg := testjson.ScanConfig{ 83 Stdout: bytes.NewReader(source), 84 Handler: &eventHandler{jsonFile: buf, formatter: format}, 85 } 86 _, err := testjson.ScanTestOutput(cfg) 87 assert.NilError(t, err) 88 89 assert.Equal(t, buf.String(), string(source)) 90 // confirm the artificial event was sent to the handler by checking the output 91 // of the formatter. 92 golden.Assert(t, errBuf.String(), "event-handler-missing-test-fail-expected") 93 } 94 95 func TestEventHandler_Event_MaxFails(t *testing.T) { 96 format := testjson.NewEventFormatter(io.Discard, "testname", testjson.FormatOptions{}) 97 98 source := golden.Get(t, "../../testjson/testdata/input/go-test-json.out") 99 cfg := testjson.ScanConfig{ 100 Stdout: bytes.NewReader(source), 101 Handler: &eventHandler{formatter: format, maxFails: 2}, 102 } 103 104 _, err := testjson.ScanTestOutput(cfg) 105 assert.Error(t, err, "ending test run because max failures was reached") 106 } 107 108 func TestNewEventHandler_CreatesDirectory(t *testing.T) { 109 dir := fs.NewDir(t, t.Name()) 110 jsonFile := filepath.Join(dir.Path(), "new-path", "log.json") 111 112 opts := &options{ 113 stdout: new(bytes.Buffer), 114 format: "testname", 115 jsonFile: jsonFile, 116 } 117 _, err := newEventHandler(opts) 118 assert.NilError(t, err) 119 120 _, err = os.Stat(jsonFile) 121 assert.NilError(t, err) 122 } 123 124 func TestWriteJunitFile_CreatesDirectory(t *testing.T) { 125 dir := fs.NewDir(t, t.Name()) 126 junitFile := filepath.Join(dir.Path(), "new-path", "junit.xml") 127 128 opts := &options{ 129 junitFile: junitFile, 130 junitTestCaseClassnameFormat: &junitFieldFormatValue{}, 131 junitTestSuiteNameFormat: &junitFieldFormatValue{}, 132 } 133 exec := &testjson.Execution{} 134 err := writeJUnitFile(opts, exec) 135 assert.NilError(t, err) 136 137 _, err = os.Stat(junitFile) 138 assert.NilError(t, err) 139 } 140 141 func TestScanTestOutput_TestTimeoutPanicRace(t *testing.T) { 142 run := func(t *testing.T, name string) { 143 format := testjson.NewEventFormatter(io.Discard, "testname", testjson.FormatOptions{}) 144 145 source := golden.Get(t, "input/go-test-json-"+name+".out") 146 cfg := testjson.ScanConfig{ 147 Stdout: bytes.NewReader(source), 148 Handler: &eventHandler{formatter: format}, 149 } 150 exec, err := testjson.ScanTestOutput(cfg) 151 assert.NilError(t, err) 152 153 out := new(bytes.Buffer) 154 testjson.PrintSummary(out, exec, testjson.SummarizeAll) 155 156 actual := text.ProcessLines(t, out, text.OpRemoveSummaryLineElapsedTime) 157 golden.Assert(t, actual, "expected/"+name+"-summary") 158 159 var buf bytes.Buffer 160 err = junitxml.Write(&buf, exec, junitxml.Config{}) 161 assert.NilError(t, err) 162 163 assert.Assert(t, cmp.Contains(buf.String(), "panic: test timed out")) 164 } 165 166 testCases := []string{ 167 "panic-race-1", 168 "panic-race-2", 169 } 170 171 for _, tc := range testCases { 172 t.Run(tc, func(t *testing.T) { 173 run(t, tc) 174 }) 175 } 176 }