term_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package termutil
  10. import (
  11. "bytes"
  12. "fmt"
  13. "testing"
  14. "devt.de/krotik/common/termutil/getch"
  15. )
  16. func TestConsoleLineTerminal(t *testing.T) {
  17. var out bytes.Buffer
  18. // Take over the low-level input interface
  19. stdin = bytes.NewBufferString("test line\n")
  20. // First test the fallback mode
  21. getchStart = func() error { return fmt.Errorf("Something is wrong") }
  22. getchGetch = func() (*getch.KeyEvent, error) { return nil, fmt.Errorf("baa") }
  23. ct, err := NewConsoleLineTerminal(&out)
  24. if err != nil {
  25. t.Error("Console terminal should go into fallback without error:", err)
  26. return
  27. }
  28. ct.StartTerm()
  29. if !ct.(*consoleLineTerminal).fallback {
  30. t.Error("Console terminal should be in fallback mode")
  31. return
  32. }
  33. l, err := ct.NextLine()
  34. if err != nil || l != "test line" {
  35. t.Error("Unexpected result:", l, err)
  36. return
  37. }
  38. l, err = ct.NextLinePrompt("", '*')
  39. if err == nil || err.Error() != "Cannot mask input characters" {
  40. t.Error("Unexpected result:", l, err)
  41. return
  42. }
  43. // Now do the proper getch supported backend
  44. getchStart = func() error { return nil }
  45. var getchbuffer []*getch.KeyEvent
  46. addTestKeyEvent := func(kc getch.KeyCode, r rune) {
  47. getchbuffer = append(getchbuffer, &getch.KeyEvent{
  48. Code: kc,
  49. Rune: r,
  50. })
  51. }
  52. getchGetch = func() (*getch.KeyEvent, error) {
  53. e := getchbuffer[0]
  54. getchbuffer = getchbuffer[1:]
  55. if e.Code == getch.KeyQuote { // Special case for tests
  56. return nil, &getch.ErrUnknownEscapeSequence{}
  57. }
  58. return e, nil
  59. }
  60. if ct, err = NewConsoleLineTerminal(&out); err != nil {
  61. t.Error(err)
  62. return
  63. }
  64. if ct.(*consoleLineTerminal).fallback {
  65. t.Error("Console terminal should NOT be in fallback mode")
  66. return
  67. }
  68. // Now do a normal line parsing
  69. addTestKeyEvent(getch.KeyT, 't')
  70. addTestKeyEvent(getch.KeyE, 'e')
  71. addTestKeyEvent(getch.KeyS, 's')
  72. addTestKeyEvent(getch.KeyT, 't')
  73. addTestKeyEvent(getch.KeyEnter, 0x00)
  74. if line, err := ct.NextLine(); err != nil || line != "test" {
  75. t.Error("Unexpected result:", "#"+line+"#", err)
  76. return
  77. }
  78. if res := string(out.Bytes()[60:67]); res != `>>>test` {
  79. t.Error("Unexpected result:", "#"+res+"#")
  80. return
  81. }
  82. out.Reset()
  83. // Now do a line parsing with masked line
  84. addTestKeyEvent(getch.KeyT, 't')
  85. addTestKeyEvent(getch.KeyE, 'e')
  86. addTestKeyEvent(getch.KeyS, 's')
  87. addTestKeyEvent(getch.KeyT, 't')
  88. addTestKeyEvent(getch.KeyEnter, 0x00)
  89. if line, err := ct.NextLinePrompt(">", '*'); err != nil || line != "test" {
  90. t.Error("Unexpected result:", "#"+line+"#", err)
  91. return
  92. }
  93. if res := string(out.Bytes()[39:44]); res != `>****` {
  94. t.Error("Unexpected result:", "#"+res+"#")
  95. return
  96. }
  97. // Now do a line parsing with pasted text
  98. addTestKeyEvent(getch.KeyT, 't')
  99. addTestKeyEvent(getch.KeyE, 'e')
  100. addTestKeyEvent(getch.KeyS, 's')
  101. addTestKeyEvent(getch.KeyT, 't')
  102. addTestKeyEvent("", 0x0)
  103. addTestKeyEvent(getch.KeyEnter, 0x00)
  104. getchbuffer[2].RawBuf = []byte("s1s")
  105. if line, err := ct.NextLine(); err != nil || line != "tes1st " {
  106. t.Error("Unexpected result:", "#"+line+"#", err)
  107. return
  108. }
  109. // Test backspace
  110. addTestKeyEvent(getch.KeyT, 't')
  111. addTestKeyEvent(getch.KeyE, 'e')
  112. addTestKeyEvent(getch.KeyS, 's')
  113. addTestKeyEvent(getch.KeyT, 't')
  114. addTestKeyEvent(getch.KeyBackspace, 0x0)
  115. addTestKeyEvent(getch.KeyBackspace, 0x0)
  116. addTestKeyEvent(getch.KeyEnter, 0x00)
  117. if line, err := ct.NextLine(); err != nil || line != "te" {
  118. t.Error("Unexpected result:", "#"+line+"#", err)
  119. return
  120. }
  121. // Test cursor movement and delete
  122. addTestKeyEvent(getch.KeyT, 't')
  123. addTestKeyEvent(getch.KeyQuote, 0x00) // Generates an unknown escape sequence error
  124. addTestKeyEvent(getch.KeyE, 'e')
  125. addTestKeyEvent(getch.KeyS, 's')
  126. addTestKeyEvent(getch.KeyT, 't')
  127. addTestKeyEvent(getch.KeyArrowLeft, 0x0)
  128. addTestKeyEvent(getch.KeyArrowLeft, 0x0)
  129. addTestKeyEvent(getch.KeyDelete, 0x0)
  130. addTestKeyEvent(getch.KeyT, 'x')
  131. addTestKeyEvent(getch.KeyArrowRight, 0x0)
  132. addTestKeyEvent(getch.KeyArrowRight, 0x0)
  133. addTestKeyEvent(getch.KeyT, 'e')
  134. addTestKeyEvent(getch.KeyT, 'r')
  135. addTestKeyEvent(getch.KeyHome, 0x0)
  136. addTestKeyEvent(getch.KeyT, '-')
  137. addTestKeyEvent(getch.KeyEnd, 0x0)
  138. addTestKeyEvent(getch.KeyT, '-')
  139. addTestKeyEvent(getch.KeyEnter, 0x00)
  140. // The unknown escape sequence error should have been ignored
  141. if line, err := ct.NextLine(); err != nil || line != "-texter-" {
  142. t.Error("Unexpected result:", "#"+line+"#", err)
  143. return
  144. }
  145. // Calling the actual stop function in getch should always be ok
  146. ct.StopTerm()
  147. }