github.com/unirita/cuto@v0.9.8-0.20160830082821-aa6652f877b7/testutil/capturer.go (about)

     1  // Copyright 2015 unirita Inc.
     2  // Created 2015/04/10 honda
     3  
     4  package testutil
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"os"
    10  )
    11  
    12  // 標準出力・標準エラー出力のキャプチャを行う構造体
    13  type Capturer struct {
    14  	isStderr bool
    15  	original *os.File
    16  	bufCh    chan string
    17  	out      *os.File
    18  	in       *os.File
    19  }
    20  
    21  // 標準出力をキャプチャするCapturerを生成する。
    22  //
    23  // return : 生成したCapturerオブジェクト
    24  func NewStdoutCapturer() *Capturer {
    25  	c := new(Capturer)
    26  	c.isStderr = false
    27  	return c
    28  }
    29  
    30  // 標準エラー出力をキャプチャするCapturerを生成する。
    31  //
    32  // return : 生成したCapturerオブジェクト
    33  func NewStderrCapturer() *Capturer {
    34  	c := new(Capturer)
    35  	c.isStderr = true
    36  	return c
    37  }
    38  
    39  // キャプチャを開始する。
    40  func (c *Capturer) Start() {
    41  	if c.isStderr {
    42  		c.original = os.Stderr
    43  	} else {
    44  		c.original = os.Stdout
    45  	}
    46  	var err error
    47  	c.in, c.out, err = os.Pipe()
    48  	if err != nil {
    49  		panic(err)
    50  	}
    51  
    52  	if c.isStderr {
    53  		os.Stderr = c.out
    54  	} else {
    55  		os.Stdout = c.out
    56  	}
    57  	c.bufCh = make(chan string)
    58  	go func() {
    59  		var b bytes.Buffer
    60  		io.Copy(&b, c.in)
    61  		c.bufCh <- b.String()
    62  	}()
    63  }
    64  
    65  // キャプチャを停止する。
    66  //
    67  // return : キャプチャ開始から停止までの間に出力された文字列
    68  func (c *Capturer) Stop() string {
    69  	c.out.Close()
    70  	defer c.in.Close()
    71  	if c.isStderr {
    72  		os.Stderr = c.original
    73  	} else {
    74  		os.Stdout = c.original
    75  	}
    76  	return <-c.bufCh
    77  }