2016-02-22 14:44:12 -05:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
2017-10-13 13:39:05 -04:00
|
|
|
// NewMockUi returns a fully initialized MockUi instance
|
|
|
|
// which is safe for concurrent use.
|
|
|
|
func NewMockUi() *MockUi {
|
|
|
|
m := new(MockUi)
|
|
|
|
m.once.Do(m.init)
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
// MockUi is a mock UI that is used for tests and is exported publicly
|
|
|
|
// for use in external tests if needed as well. Do not instantite this
|
|
|
|
// directly since the buffers will be initialized on the first write. If
|
|
|
|
// there is no write then you will get a nil panic. Please use the
|
|
|
|
// NewMockUi() constructor function instead. You can fix your code with
|
|
|
|
//
|
|
|
|
// sed -i -e 's/new(cli.MockUi)/cli.NewMockUi()/g' *_test.go
|
2016-02-22 14:44:12 -05:00
|
|
|
type MockUi struct {
|
|
|
|
InputReader io.Reader
|
2017-10-13 13:39:05 -04:00
|
|
|
ErrorWriter *syncBuffer
|
|
|
|
OutputWriter *syncBuffer
|
2016-02-22 14:44:12 -05:00
|
|
|
|
|
|
|
once sync.Once
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) Ask(query string) (string, error) {
|
|
|
|
u.once.Do(u.init)
|
|
|
|
|
|
|
|
var result string
|
|
|
|
fmt.Fprint(u.OutputWriter, query)
|
|
|
|
if _, err := fmt.Fscanln(u.InputReader, &result); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) AskSecret(query string) (string, error) {
|
|
|
|
return u.Ask(query)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) Error(message string) {
|
|
|
|
u.once.Do(u.init)
|
|
|
|
|
|
|
|
fmt.Fprint(u.ErrorWriter, message)
|
|
|
|
fmt.Fprint(u.ErrorWriter, "\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) Info(message string) {
|
|
|
|
u.Output(message)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) Output(message string) {
|
|
|
|
u.once.Do(u.init)
|
|
|
|
|
|
|
|
fmt.Fprint(u.OutputWriter, message)
|
|
|
|
fmt.Fprint(u.OutputWriter, "\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) Warn(message string) {
|
|
|
|
u.once.Do(u.init)
|
|
|
|
|
|
|
|
fmt.Fprint(u.ErrorWriter, message)
|
|
|
|
fmt.Fprint(u.ErrorWriter, "\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *MockUi) init() {
|
2017-10-13 13:39:05 -04:00
|
|
|
u.ErrorWriter = new(syncBuffer)
|
|
|
|
u.OutputWriter = new(syncBuffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
type syncBuffer struct {
|
|
|
|
sync.RWMutex
|
|
|
|
b bytes.Buffer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *syncBuffer) Write(data []byte) (int, error) {
|
|
|
|
b.Lock()
|
|
|
|
defer b.Unlock()
|
|
|
|
return b.b.Write(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *syncBuffer) Read(data []byte) (int, error) {
|
|
|
|
b.RLock()
|
|
|
|
defer b.RUnlock()
|
|
|
|
return b.b.Read(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *syncBuffer) Reset() {
|
|
|
|
b.Lock()
|
|
|
|
b.b.Reset()
|
|
|
|
b.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *syncBuffer) String() string {
|
|
|
|
return string(b.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *syncBuffer) Bytes() []byte {
|
|
|
|
b.RLock()
|
|
|
|
data := b.b.Bytes()
|
|
|
|
b.RUnlock()
|
|
|
|
return data
|
2016-02-22 14:44:12 -05:00
|
|
|
}
|