terminal_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2011 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. package terminal
  5. import (
  6. "io"
  7. "testing"
  8. )
  9. type MockTerminal struct {
  10. toSend []byte
  11. bytesPerRead int
  12. received []byte
  13. }
  14. func (c *MockTerminal) Read(data []byte) (n int, err error) {
  15. n = len(data)
  16. if n == 0 {
  17. return
  18. }
  19. if n > len(c.toSend) {
  20. n = len(c.toSend)
  21. }
  22. if n == 0 {
  23. return 0, io.EOF
  24. }
  25. if c.bytesPerRead > 0 && n > c.bytesPerRead {
  26. n = c.bytesPerRead
  27. }
  28. copy(data, c.toSend[:n])
  29. c.toSend = c.toSend[n:]
  30. return
  31. }
  32. func (c *MockTerminal) Write(data []byte) (n int, err error) {
  33. c.received = append(c.received, data...)
  34. return len(data), nil
  35. }
  36. func TestClose(t *testing.T) {
  37. c := &MockTerminal{}
  38. ss := NewTerminal(c, "> ")
  39. line, err := ss.ReadLine()
  40. if line != "" {
  41. t.Errorf("Expected empty line but got: %s", line)
  42. }
  43. if err != io.EOF {
  44. t.Errorf("Error should have been EOF but got: %s", err)
  45. }
  46. }
  47. var keyPressTests = []struct {
  48. in string
  49. line string
  50. err error
  51. throwAwayLines int
  52. }{
  53. {
  54. err: io.EOF,
  55. },
  56. {
  57. in: "\r",
  58. line: "",
  59. },
  60. {
  61. in: "foo\r",
  62. line: "foo",
  63. },
  64. {
  65. in: "a\x1b[Cb\r", // right
  66. line: "ab",
  67. },
  68. {
  69. in: "a\x1b[Db\r", // left
  70. line: "ba",
  71. },
  72. {
  73. in: "a\177b\r", // backspace
  74. line: "b",
  75. },
  76. {
  77. in: "\x1b[A\r", // up
  78. },
  79. {
  80. in: "\x1b[B\r", // down
  81. },
  82. {
  83. in: "line\x1b[A\x1b[B\r", // up then down
  84. line: "line",
  85. },
  86. {
  87. in: "line1\rline2\x1b[A\r", // recall previous line.
  88. line: "line1",
  89. throwAwayLines: 1,
  90. },
  91. {
  92. // recall two previous lines and append.
  93. in: "line1\rline2\rline3\x1b[A\x1b[Axxx\r",
  94. line: "line1xxx",
  95. throwAwayLines: 2,
  96. },
  97. }
  98. func TestKeyPresses(t *testing.T) {
  99. for i, test := range keyPressTests {
  100. for j := 0; j < len(test.in); j++ {
  101. c := &MockTerminal{
  102. toSend: []byte(test.in),
  103. bytesPerRead: j,
  104. }
  105. ss := NewTerminal(c, "> ")
  106. for k := 0; k < test.throwAwayLines; k++ {
  107. _, err := ss.ReadLine()
  108. if err != nil {
  109. t.Errorf("Throwaway line %d from test %d resulted in error: %s", k, i, err)
  110. }
  111. }
  112. line, err := ss.ReadLine()
  113. if line != test.line {
  114. t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line)
  115. break
  116. }
  117. if err != test.err {
  118. t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err)
  119. break
  120. }
  121. }
  122. }
  123. }