package tokenize import ( "testing" ) func TestFork_CreatesForkOfInputAtSameCursorPosition(t *testing.T) { // Create input, accept the first rune. i := NewAPI("Testing") r, _, _ := i.Input.PeekRune(0) i.Input.AcceptRune(r) // T AssertEqual(t, "T", i.dataAsString(), "accepted rune in input") // Fork child := i.Fork() AssertEqual(t, 1, i.stackFrame.offset, "parent offset") AssertEqual(t, 1, i.stackFrame.offset, "child offset") // Accept two runes via fork. r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // e r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // s AssertEqual(t, "es", i.dataAsString(), "result runes in fork") AssertEqual(t, 1, i.stackFrames[i.stackLevel-1].offset, "parent offset") AssertEqual(t, 3, i.stackFrame.offset, "child offset") // Merge fork back into parent i.Merge(child) i.Dispose(child) AssertEqual(t, "Tes", i.dataAsString(), "result runes in parent Input after Merge()") AssertEqual(t, 3, i.stackFrame.offset, "parent offset") } func TestGivenForkedChildWhichAcceptedRune_AfterMerging_RuneEndsUpInParentResult(t *testing.T) { i := NewAPI("Testing") r, _, _ := i.Input.PeekRune(0) i.Input.AcceptRune(r) // T f1 := i.Fork() r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // e f2 := i.Fork() r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // s AssertEqual(t, "s", i.dataAsString(), "f2 String()") AssertEqual(t, 3, i.stackFrame.offset, "f2.offset A") i.Merge(f2) i.Dispose(f2) AssertEqual(t, "es", i.dataAsString(), "f1 String()") AssertEqual(t, 3, i.stackFrame.offset, "f1.offset A") i.Merge(f1) i.Dispose(f1) AssertEqual(t, "Tes", i.dataAsString(), "top-level API String()") AssertEqual(t, 3, i.stackFrame.offset, "f1.offset A") } func TestFlushInput(t *testing.T) { i := NewAPI("cool") // Flushing without any read data is okay. FlushInput() will return // false in this case, and nothing else happens. AssertTrue(t, i.Input.Flush() == false, "flush input at start") r, _, _ := i.Input.PeekRune(0) i.Input.AcceptRune(r) // c r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // o AssertTrue(t, i.Input.Flush() == true, "flush input after reading some data") AssertEqual(t, 0, i.stackFrame.offset, "offset after flush input") AssertTrue(t, i.Input.Flush() == false, "flush input after flush input") // Read offset is now zero, but reading should continue after "co". // The output so far isn't modified, so the following accept calls // will add their runes to the already accepted string "co". r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // o r, _, _ = i.Input.PeekRune(0) i.Input.AcceptRune(r) // o AssertEqual(t, "cool", i.dataAsString(), "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.dataAsString(), "runes after 1 read") flushB(api) AssertEqual(t, 0, api.stackFrame.offset, "offset after 2 reads + input flush") AssertEqual(t, "ab", api.dataAsString(), "runes after 2 reads") runeA(api) AssertEqual(t, 1, api.stackFrame.offset, "offset after 3 reads") AssertEqual(t, "aba", api.dataAsString(), "runes after 3 reads") runeA(api) AssertEqual(t, 2, api.stackFrame.offset, "offset after 4 reads") AssertEqual(t, "abaa", api.dataAsString(), "runes after 4 reads") flushB(api) AssertEqual(t, 0, api.stackFrame.offset, "offset after 5 reads + input flush") AssertEqual(t, "abaab", api.dataAsString(), "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) } }