ui_mock.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package cli
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "sync"
  7. )
  8. // NewMockUi returns a fully initialized MockUi instance
  9. // which is safe for concurrent use.
  10. func NewMockUi() *MockUi {
  11. m := new(MockUi)
  12. m.once.Do(m.init)
  13. return m
  14. }
  15. // MockUi is a mock UI that is used for tests and is exported publicly
  16. // for use in external tests if needed as well. Do not instantite this
  17. // directly since the buffers will be initialized on the first write. If
  18. // there is no write then you will get a nil panic. Please use the
  19. // NewMockUi() constructor function instead. You can fix your code with
  20. //
  21. // sed -i -e 's/new(cli.MockUi)/cli.NewMockUi()/g' *_test.go
  22. type MockUi struct {
  23. InputReader io.Reader
  24. ErrorWriter *syncBuffer
  25. OutputWriter *syncBuffer
  26. once sync.Once
  27. }
  28. func (u *MockUi) Ask(query string) (string, error) {
  29. u.once.Do(u.init)
  30. var result string
  31. fmt.Fprint(u.OutputWriter, query)
  32. if _, err := fmt.Fscanln(u.InputReader, &result); err != nil {
  33. return "", err
  34. }
  35. return result, nil
  36. }
  37. func (u *MockUi) AskSecret(query string) (string, error) {
  38. return u.Ask(query)
  39. }
  40. func (u *MockUi) Error(message string) {
  41. u.once.Do(u.init)
  42. fmt.Fprint(u.ErrorWriter, message)
  43. fmt.Fprint(u.ErrorWriter, "\n")
  44. }
  45. func (u *MockUi) Info(message string) {
  46. u.Output(message)
  47. }
  48. func (u *MockUi) Output(message string) {
  49. u.once.Do(u.init)
  50. fmt.Fprint(u.OutputWriter, message)
  51. fmt.Fprint(u.OutputWriter, "\n")
  52. }
  53. func (u *MockUi) Warn(message string) {
  54. u.once.Do(u.init)
  55. fmt.Fprint(u.ErrorWriter, message)
  56. fmt.Fprint(u.ErrorWriter, "\n")
  57. }
  58. func (u *MockUi) init() {
  59. u.ErrorWriter = new(syncBuffer)
  60. u.OutputWriter = new(syncBuffer)
  61. }
  62. type syncBuffer struct {
  63. sync.RWMutex
  64. b bytes.Buffer
  65. }
  66. func (b *syncBuffer) Write(data []byte) (int, error) {
  67. b.Lock()
  68. defer b.Unlock()
  69. return b.b.Write(data)
  70. }
  71. func (b *syncBuffer) Read(data []byte) (int, error) {
  72. b.RLock()
  73. defer b.RUnlock()
  74. return b.b.Read(data)
  75. }
  76. func (b *syncBuffer) Reset() {
  77. b.Lock()
  78. b.b.Reset()
  79. b.Unlock()
  80. }
  81. func (b *syncBuffer) String() string {
  82. return string(b.Bytes())
  83. }
  84. func (b *syncBuffer) Bytes() []byte {
  85. b.RLock()
  86. data := b.b.Bytes()
  87. b.RUnlock()
  88. return data
  89. }