diff --git a/examples/singleapp/main_stdout_ospipe/.gitignore b/examples/singleapp/main_stdout_ospipe/.gitignore new file mode 100644 index 0000000..7a0b7f0 --- /dev/null +++ b/examples/singleapp/main_stdout_ospipe/.gitignore @@ -0,0 +1 @@ +app \ No newline at end of file diff --git a/examples/singleapp/main_stdout_ospipe/Taskfile.yml b/examples/singleapp/main_stdout_ospipe/Taskfile.yml new file mode 100644 index 0000000..189bec9 --- /dev/null +++ b/examples/singleapp/main_stdout_ospipe/Taskfile.yml @@ -0,0 +1,10 @@ +# https://taskfile.dev + +version: '3' + +tasks: + default: + cmds: + - go build -o app . + - ./app -v "hello" -v "world" -v "へろー" -v "ワールド" + - go test . diff --git a/examples/singleapp/main_stdout_ospipe/main.go b/examples/singleapp/main_stdout_ospipe/main.go new file mode 100644 index 0000000..ab5edec --- /dev/null +++ b/examples/singleapp/main_stdout_ospipe/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "flag" + "fmt" + "strings" +) + +type ( + vars []string +) + +func (me *vars) String() string { + return fmt.Sprint(*me) +} + +func (me *vars) Set(v string) error { + *me = append(*me, v) + return nil +} + +var ( + _ flag.Value = (*vars)(nil) +) + +func main() { + var ( + vs vars + ) + flag.Var(&vs, "v", "values") + flag.Parse() + + fmt.Println(strings.Join(vs, ",")) +} diff --git a/examples/singleapp/main_stdout_ospipe/main_test.go b/examples/singleapp/main_stdout_ospipe/main_test.go new file mode 100644 index 0000000..c4ff3fe --- /dev/null +++ b/examples/singleapp/main_stdout_ospipe/main_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "bytes" + "io" + "os" + "sync" + "testing" +) + +func TestMainOutput(t *testing.T) { + // 元の標準出力を退避させ、パイプのWriter側に差し替え + old := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + defer func() { + // 元に戻す。このプログラムはこのまま終了するので別にしなくて良いが習慣として。 + os.Stdout = old + }() + + // コマンドライン引数 + os.Args = append(os.Args, "-v", "hello", "-v", "world", "-v", "へろー", "-v", "ワールド") + + var wg sync.WaitGroup + wg.Add(1) + + // パイプはノンバッファリングなので非同期処理が必須 + go func() { + defer wg.Done() + defer w.Close() + main() + }() + + wg.Wait() + + // 出力内容を確認 + want := []byte("hello,world,へろー,ワールド\n") + got, _ := io.ReadAll(r) + if !bytes.Equal(want, got) { + t.Errorf("want: %s\tgot: %s", want, got) + } +}