streamlexer_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package buffer // import "github.com/tdewolff/parse/buffer"
  2. import (
  3. "bytes"
  4. "io"
  5. "testing"
  6. "github.com/tdewolff/test"
  7. )
  8. func TestBufferPool(t *testing.T) {
  9. z := &bufferPool{}
  10. lorem := []byte("Lorem ipsum")
  11. dolor := []byte("dolor sit amet")
  12. consectetur := []byte("consectetur adipiscing elit")
  13. // set lorem as first buffer and get new dolor buffer
  14. b := z.swap(lorem, len(dolor))
  15. test.That(t, len(b) == 0)
  16. test.That(t, cap(b) == len(dolor))
  17. b = append(b, dolor...)
  18. // free first buffer so it will be reused
  19. z.free(len(lorem))
  20. b = z.swap(b, len(lorem))
  21. b = b[:len(lorem)]
  22. test.Bytes(t, b, lorem)
  23. b = z.swap(b, len(consectetur))
  24. b = append(b, consectetur...)
  25. // free in advance to reuse the same buffer
  26. z.free(len(dolor) + len(lorem) + len(consectetur))
  27. test.That(t, z.head == 0)
  28. b = z.swap(b, len(consectetur))
  29. b = b[:len(consectetur)]
  30. test.Bytes(t, b, consectetur)
  31. // free in advance but request larger buffer
  32. z.free(len(consectetur))
  33. b = z.swap(b, len(consectetur)+1)
  34. b = append(b, consectetur...)
  35. b = append(b, '.')
  36. test.That(t, cap(b) == len(consectetur)+1)
  37. }
  38. func TestStreamLexer(t *testing.T) {
  39. s := `Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
  40. z := NewStreamLexer(bytes.NewBufferString(s))
  41. test.T(t, z.err, io.EOF, "buffer must be fully in memory")
  42. test.T(t, z.Err(), nil, "buffer is at EOF but must not return EOF until we reach that")
  43. test.That(t, z.Pos() == 0, "buffer must start at position 0")
  44. test.That(t, z.Peek(0) == 'L', "first character must be 'L'")
  45. test.That(t, z.Peek(1) == 'o', "second character must be 'o'")
  46. z.Move(1)
  47. test.That(t, z.Peek(0) == 'o', "must be 'o' at position 1")
  48. test.That(t, z.Peek(1) == 'r', "must be 'r' at position 1")
  49. z.Rewind(6)
  50. test.That(t, z.Peek(0) == 'i', "must be 'i' at position 6")
  51. test.That(t, z.Peek(1) == 'p', "must be 'p' at position 7")
  52. test.Bytes(t, z.Lexeme(), []byte("Lorem "), "buffered string must now read 'Lorem ' when at position 6")
  53. test.Bytes(t, z.Shift(), []byte("Lorem "), "shift must return the buffered string")
  54. test.That(t, z.ShiftLen() == len("Lorem "), "shifted length must equal last shift")
  55. test.That(t, z.Pos() == 0, "after shifting position must be 0")
  56. test.That(t, z.Peek(0) == 'i', "must be 'i' at position 0 after shifting")
  57. test.That(t, z.Peek(1) == 'p', "must be 'p' at position 1 after shifting")
  58. test.T(t, z.Err(), nil, "error must be nil at this point")
  59. z.Move(len(s) - len("Lorem ") - 1)
  60. test.T(t, z.Err(), nil, "error must be nil just before the end of the buffer")
  61. z.Skip()
  62. test.That(t, z.Pos() == 0, "after skipping position must be 0")
  63. z.Move(1)
  64. test.T(t, z.Err(), io.EOF, "error must be EOF when past the buffer")
  65. z.Move(-1)
  66. test.T(t, z.Err(), nil, "error must be nil just before the end of the buffer, even when it has been past the buffer")
  67. z.Free(0) // has already been tested
  68. }
  69. func TestStreamLexerShift(t *testing.T) {
  70. s := `Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
  71. z := NewStreamLexerSize(test.NewPlainReader(bytes.NewBufferString(s)), 5)
  72. z.Move(len("Lorem "))
  73. test.Bytes(t, z.Shift(), []byte("Lorem "), "shift must return the buffered string")
  74. test.That(t, z.ShiftLen() == len("Lorem "), "shifted length must equal last shift")
  75. }
  76. func TestStreamLexerSmall(t *testing.T) {
  77. s := `abcdefghijklm`
  78. z := NewStreamLexerSize(test.NewPlainReader(bytes.NewBufferString(s)), 4)
  79. test.That(t, z.Peek(8) == 'i', "first character must be 'i' at position 8")
  80. z = NewStreamLexerSize(test.NewPlainReader(bytes.NewBufferString(s)), 4)
  81. test.That(t, z.Peek(12) == 'm', "first character must be 'm' at position 12")
  82. z = NewStreamLexerSize(test.NewPlainReader(bytes.NewBufferString(s)), 0)
  83. test.That(t, z.Peek(4) == 'e', "first character must be 'e' at position 4")
  84. z = NewStreamLexerSize(test.NewPlainReader(bytes.NewBufferString(s)), 13)
  85. test.That(t, z.Peek(13) == 0, "must yield error at position 13")
  86. }
  87. func TestStreamLexerSingle(t *testing.T) {
  88. z := NewStreamLexer(test.NewInfiniteReader())
  89. test.That(t, z.Peek(0) == '.')
  90. test.That(t, z.Peek(1) == '.')
  91. test.That(t, z.Peek(3) == '.', "required two successful reads")
  92. }
  93. func TestStreamLexerRunes(t *testing.T) {
  94. z := NewStreamLexer(bytes.NewBufferString("aæ†\U00100000"))
  95. r, n := z.PeekRune(0)
  96. test.That(t, n == 1, "first character must be length 1")
  97. test.That(t, r == 'a', "first character must be rune 'a'")
  98. r, n = z.PeekRune(1)
  99. test.That(t, n == 2, "second character must be length 2")
  100. test.That(t, r == 'æ', "second character must be rune 'æ'")
  101. r, n = z.PeekRune(3)
  102. test.That(t, n == 3, "fourth character must be length 3")
  103. test.That(t, r == '†', "fourth character must be rune '†'")
  104. r, n = z.PeekRune(6)
  105. test.That(t, n == 4, "seventh character must be length 4")
  106. test.That(t, r == '\U00100000', "seventh character must be rune '\U00100000'")
  107. }
  108. func TestStreamLexerBadRune(t *testing.T) {
  109. z := NewStreamLexer(bytes.NewBufferString("\xF0")) // expect four byte rune
  110. r, n := z.PeekRune(0)
  111. test.T(t, n, 4, "length")
  112. test.T(t, r, rune(0), "rune")
  113. }
  114. func TestStreamLexerZeroLen(t *testing.T) {
  115. z := NewStreamLexer(test.NewPlainReader(bytes.NewBufferString("")))
  116. test.That(t, z.Peek(0) == 0, "first character must yield error")
  117. }
  118. func TestStreamLexerEmptyReader(t *testing.T) {
  119. z := NewStreamLexer(test.NewEmptyReader())
  120. test.That(t, z.Peek(0) == 0, "first character must yield error")
  121. test.T(t, z.Err(), io.EOF, "error must be EOF")
  122. test.That(t, z.Peek(0) == 0, "second peek must also yield error")
  123. }