1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build !(windows || js || wasip1)
6
7package main
8
9import (
10	"regexp"
11	"strings"
12	"testing"
13)
14
15func TestExitCodeFilter(t *testing.T) {
16	// Write text to the filter one character at a time.
17	var out strings.Builder
18	f, exitStr := newExitCodeFilter(&out)
19	// Embed a "fake" exit code in the middle to check that we don't get caught on it.
20	pre := "abc" + exitStr + "123def"
21	text := pre + exitStr + `1`
22	for i := 0; i < len(text); i++ {
23		_, err := f.Write([]byte{text[i]})
24		if err != nil {
25			t.Fatal(err)
26		}
27	}
28
29	// The "pre" output should all have been flushed already.
30	if want, got := pre, out.String(); want != got {
31		t.Errorf("filter should have already flushed %q, but flushed %q", want, got)
32	}
33
34	code, err := f.Finish()
35	if err != nil {
36		t.Fatal(err)
37	}
38
39	// Nothing more should have been written to out.
40	if want, got := pre, out.String(); want != got {
41		t.Errorf("want output %q, got %q", want, got)
42	}
43	if want := 1; want != code {
44		t.Errorf("want exit code %d, got %d", want, code)
45	}
46}
47
48func TestExitCodeMissing(t *testing.T) {
49	var wantErr *regexp.Regexp
50	check := func(text string) {
51		t.Helper()
52		var out strings.Builder
53		f, exitStr := newExitCodeFilter(&out)
54		if want := "exitcode="; want != exitStr {
55			t.Fatalf("test assumes exitStr will be %q, but got %q", want, exitStr)
56		}
57		f.Write([]byte(text))
58		_, err := f.Finish()
59		// We should get a no exit code error
60		if err == nil || !wantErr.MatchString(err.Error()) {
61			t.Errorf("want error matching %s, got %s", wantErr, err)
62		}
63		// And it should flush all output (even if it looks
64		// like we may be getting an exit code)
65		if got := out.String(); text != got {
66			t.Errorf("want full output %q, got %q", text, got)
67		}
68	}
69	wantErr = regexp.MustCompile("^no exit code")
70	check("abc")
71	check("exitcode")
72	check("exitcode=")
73	check("exitcode=123\n")
74	wantErr = regexp.MustCompile("^bad exit code: .* value out of range")
75	check("exitcode=999999999999999999999999")
76}
77