go-parsekit/tokenize/tokenizer_whitebox_test.go

132 lines
4.3 KiB
Go

package tokenize
import (
"testing"
)
func TestFork_CreatesForkOfInputAtSameCursorPosition(t *testing.T) {
// Create input, accept the first rune.
i := NewAPI("Testing")
i.NextRune()
i.Accept() // T
AssertEqual(t, "T", i.String(), "accepted rune in input")
// Fork
child := i.Fork()
AssertEqual(t, 1, i.stackFrame.cursor.Byte, "parent cursor.Byte")
AssertEqual(t, 1, i.stackFrame.offset, "parent offset")
AssertEqual(t, 1, i.stackFrame.cursor.Byte, "child cursor.Byte")
AssertEqual(t, 1, i.stackFrame.offset, "child offset")
// Accept two runes via fork.
i.NextRune()
i.Accept() // e
i.NextRune()
i.Accept() // s
AssertEqual(t, "es", i.String(), "result runes in fork")
AssertEqual(t, 1, i.stackFrames[i.stackLevel-1].cursor.Byte, "parent cursor.Byte")
AssertEqual(t, 1, i.stackFrames[i.stackLevel-1].offset, "parent offset")
AssertEqual(t, 3, i.stackFrame.cursor.Byte, "child cursor.Byte")
AssertEqual(t, 3, i.stackFrame.offset, "child offset")
// Merge fork back into parent
i.Merge(child)
i.Dispose(child)
AssertEqual(t, "Tes", i.String(), "result runes in parent Input after Merge()")
AssertEqual(t, 3, i.stackFrame.cursor.Byte, "parent cursor.Byte")
AssertEqual(t, 3, i.stackFrame.offset, "parent offset")
}
func TestGivenForkedChildWhichAcceptedRune_AfterMerging_RuneEndsUpInParentResult(t *testing.T) {
i := NewAPI("Testing")
i.NextRune()
i.Accept()
f1 := i.Fork()
i.NextRune()
i.Accept()
f2 := i.Fork()
i.NextRune()
i.Accept()
AssertEqual(t, "s", i.String(), "f2 String()")
AssertEqual(t, 3, i.stackFrame.offset, "f2.offset A")
i.Merge(f2)
i.Dispose(f2)
AssertEqual(t, "es", i.String(), "f1 String()")
AssertEqual(t, 3, i.stackFrame.offset, "f1.offset A")
i.Merge(f1)
i.Dispose(f1)
AssertEqual(t, "Tes", i.String(), "top-level API String()")
AssertEqual(t, 3, i.stackFrame.offset, "f1.offset A")
}
func TestCallingAcceptAfterNextRune_AcceptsRuneAndMovesReadOffsetForward(t *testing.T) {
i := NewAPI("Testing")
r, _ := i.NextRune()
AssertEqual(t, 'T', r, "result from 1st call to NextRune()")
AssertTrue(t, i.lastRune == 'T', "API.lastRune after NextRune() is not 'T'")
AssertTrue(t, i.runeRead, "API.runeRead after NextRune() is not true")
i.Accept()
AssertTrue(t, i.runeRead == false, "API.runeRead after Accept() is not false")
AssertEqual(t, 1, i.stackFrame.offset, "API.stackFrame.offset")
r, _ = i.NextRune()
AssertEqual(t, 'e', r, "result from 2nd call to NextRune()")
}
func TestFlushInput(t *testing.T) {
api := NewAPI("cool")
// Flushing without any read data is okay. FlushInput() will return
// false in this case, and nothing else happens.
AssertTrue(t, api.FlushInput() == false, "flush input at start")
api.NextRune()
api.Accept()
api.NextRune()
api.Accept()
AssertTrue(t, api.FlushInput() == true, "flush input after reading some data")
AssertEqual(t, 0, api.stackFrame.offset, "offset after flush input")
AssertTrue(t, api.FlushInput() == false, "flush input after flush input")
// Read offset is now zero, but reading should continue after "co".
api.NextRune()
api.Accept()
api.NextRune()
api.Accept()
AssertEqual(t, "cool", api.String(), "end result")
}
func TestInputFlusherWrapper(t *testing.T) {
runeA := A.Rune('a')
flushB := C.FlushInput(A.Rune('b'))
api := NewAPI("abaab")
runeA(api)
AssertEqual(t, 1, api.stackFrame.offset, "offset after 1 read")
AssertEqual(t, "a", api.String(), "runes after 1 read")
flushB(api)
AssertEqual(t, 0, api.stackFrame.offset, "offset after 2 reads + input flush")
AssertEqual(t, "ab", api.String(), "runes after 2 reads")
runeA(api)
AssertEqual(t, 1, api.stackFrame.offset, "offset after 3 reads")
AssertEqual(t, "aba", api.String(), "runes after 3 reads")
runeA(api)
AssertEqual(t, 2, api.stackFrame.offset, "offset after 4 reads")
AssertEqual(t, "abaa", api.String(), "runes after 4 reads")
flushB(api)
AssertEqual(t, 0, api.stackFrame.offset, "offset after 5 reads + input flush")
AssertEqual(t, "abaab", api.String(), "runes after 5 reads")
}
func AssertEqual(t *testing.T, expected interface{}, actual interface{}, forWhat string) {
if expected != actual {
t.Errorf(
"Unexpected value for %s:\nexpected: %q\nactual: %q",
forWhat, expected, actual)
}
}
func AssertTrue(t *testing.T, b bool, assertion string) {
if !b {
t.Errorf("Assertion %s is false", assertion)
}
}