Source file src/testing/flag_test.go

     1  // Copyright 2022 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  package testing_test
     6  
     7  import (
     8  	"flag"
     9  	"internal/testenv"
    10  	"os"
    11  	"os/exec"
    12  	"testing"
    13  )
    14  
    15  var testFlagArg = flag.String("test_flag_arg", "", "TestFlag: passing -v option")
    16  
    17  const flagTestEnv = "GO_WANT_FLAG_HELPER_PROCESS"
    18  
    19  func TestFlag(t *testing.T) {
    20  	if os.Getenv(flagTestEnv) == "1" {
    21  		testFlagHelper(t)
    22  		return
    23  	}
    24  
    25  	testenv.MustHaveExec(t)
    26  
    27  	for _, flag := range []string{"", "-test.v", "-test.v=test2json"} {
    28  		flag := flag
    29  		t.Run(flag, func(t *testing.T) {
    30  			t.Parallel()
    31  			exe, err := os.Executable()
    32  			if err != nil {
    33  				exe = os.Args[0]
    34  			}
    35  			cmd := exec.Command(exe, "-test.run=^TestFlag$", "-test_flag_arg="+flag)
    36  			if flag != "" {
    37  				cmd.Args = append(cmd.Args, flag)
    38  			}
    39  			cmd.Env = append(cmd.Environ(), flagTestEnv+"=1")
    40  			b, err := cmd.CombinedOutput()
    41  			if len(b) > 0 {
    42  				// When we set -test.v=test2json, we need to escape the ^V control
    43  				// character used for JSON framing so that the JSON parser doesn't
    44  				// misinterpret the subprocess output as output from the parent test.
    45  				t.Logf("%q", b)
    46  			}
    47  			if err != nil {
    48  				t.Error(err)
    49  			}
    50  		})
    51  	}
    52  }
    53  
    54  // testFlagHelper is called by the TestFlagHelper subprocess.
    55  func testFlagHelper(t *testing.T) {
    56  	f := flag.Lookup("test.v")
    57  	if f == nil {
    58  		t.Fatal(`flag.Lookup("test.v") failed`)
    59  	}
    60  
    61  	bf, ok := f.Value.(interface{ IsBoolFlag() bool })
    62  	if !ok {
    63  		t.Errorf("test.v flag (type %T) does not have IsBoolFlag method", f)
    64  	} else if !bf.IsBoolFlag() {
    65  		t.Error("test.v IsBoolFlag() returned false")
    66  	}
    67  
    68  	gf, ok := f.Value.(flag.Getter)
    69  	if !ok {
    70  		t.Fatalf("test.v flag (type %T) does not have Get method", f)
    71  	}
    72  	v := gf.Get()
    73  
    74  	var want any
    75  	switch *testFlagArg {
    76  	case "":
    77  		want = false
    78  	case "-test.v":
    79  		want = true
    80  	case "-test.v=test2json":
    81  		want = "test2json"
    82  	default:
    83  		t.Fatalf("unexpected test_flag_arg %q", *testFlagArg)
    84  	}
    85  
    86  	if v != want {
    87  		t.Errorf("test.v is %v want %v", v, want)
    88  	}
    89  }
    90  

View as plain text