# Builds and runs test binaries, so skip in short mode.
[short] skip

env GO111MODULE=on

# If a test invoked by 'go test' exits with a zero status code,
# it will panic.
! go test ./zero
! stdout ^ok
! stdout 'exit status'
stdout 'panic'
stdout ^FAIL

# If a test exits with a non-zero status code, 'go test' fails normally.
! go test ./one
! stdout ^ok
stdout 'exit status'
! stdout 'panic'
stdout ^FAIL

# Ensure that other flags still do the right thing.
go test -list=. ./zero
stdout ExitZero

! go test -bench=. ./zero
stdout 'panic'

# 'go test' with no args streams output without buffering. Ensure that it still
# catches a zero exit with missing output.
cd zero
! go test
stdout 'panic'
cd ../normal
go test
stdout ^ok
cd ..

# If a TestMain exits with a zero status code, 'go test' shouldn't
# complain about that. It's a common way to skip testing a package
# entirely.
go test ./main_zero
! stdout 'skipping all tests'
stdout ^ok

# With -v, we'll see the warning from TestMain.
go test -v ./main_zero
stdout 'skipping all tests'
stdout ^ok

# Listing all tests won't actually give a result if TestMain exits. That's okay,
# because this is how TestMain works. If we decide to support -list even when
# TestMain is used to skip entire packages, we can change this test case.
go test -list=. ./main_zero
stdout 'skipping all tests'
! stdout TestNotListed

# Running the test directly still fails, if we pass the flag.
go test -c -o ./zero.exe ./zero
! exec ./zero.exe -test.paniconexit0

# Using -json doesn't affect the exit status.
! go test -json ./zero
! stdout '"Output":"ok'
! stdout 'exit status'
stdout 'panic'
stdout '"Output":"FAIL'

# Running the test via test2json also fails.
! go tool test2json ./zero.exe -test.v -test.paniconexit0
! stdout '"Output":"ok'
! stdout 'exit status'
stdout 'panic'

-- go.mod --
module m

-- ./normal/normal.go --
package normal
-- ./normal/normal_test.go --
package normal

import "testing"

func TestExitZero(t *testing.T) {
}

-- ./zero/zero.go --
package zero
-- ./zero/zero_test.go --
package zero

import (
	"os"
	"testing"
)

func TestExitZero(t *testing.T) {
	os.Exit(0)
}

-- ./one/one.go --
package one
-- ./one/one_test.go --
package one

import (
	"os"
	"testing"
)

func TestExitOne(t *testing.T) {
	os.Exit(1)
}

-- ./main_zero/zero.go --
package zero
-- ./main_zero/zero_test.go --
package zero

import (
	"fmt"
	"os"
	"testing"
)

func TestMain(m *testing.M) {
	fmt.Println("skipping all tests")
	os.Exit(0)
}

func TestNotListed(t *testing.T) {}
