package typeset import "slices" import "testing" func rl (run rune) runeLayout { return runeLayout { run: run } } func tk (kind tokenKind, value string) token { tok := token { kind: kind, } runeValue := []rune(value) tok.runes = make([]runeLayout, len(runeValue)) for index, run := range runeValue { tok.runes[index] = rl(run) } return tok } func compareTokens (got, correct []token) bool { for index, tok := range got { correctTok := correct[index] isCorrect := correctTok.kind == tok.kind && correctTok.width == tok.width && slices.Equal(correctTok.runes, tok.runes) if !isCorrect { return false } } return true } func logTokens (test *testing.T, tokens []token) { for _, token := range tokens { test.Logf("- %-40v | %v", token, token.runes) } } func TestParseString (test *testing.T) { // ---- processing ---- runes, tokens := parseString("hello \rworld!\nfoo\n\r\nbar\tbaz\t\tsomething") // ---- correct data ---- correctRunes := []runeLayout { rl('h'), rl('e'), rl('l'), rl('l'), rl('o'), rl(' '), rl('\r'), rl('w'), rl('o'), rl('r'), rl('l'), rl('d'), rl('!'), rl('\n'), rl('f'), rl('o'), rl('o'), rl('\n'), rl('\r'), rl('\n'), rl('b'), rl('a'), rl('r'), rl('\t'), rl('b'), rl('a'), rl('z'), rl('\t'), rl('\t'), rl('s'), rl('o'), rl('m'), rl('e'), rl('t'), rl('h'), rl('i'), rl('n'), rl('g'), } correctTokens := []token { tk(tokenKindWord, "hello"), tk(tokenKindSpace, " "), tk(tokenKindWord, "\rworld!"), tk(tokenKindLineBreak, "\n"), tk(tokenKindWord, "foo"), tk(tokenKindLineBreak, "\n"), tk(tokenKindLineBreak, "\r\n"), tk(tokenKindWord, "bar"), tk(tokenKindTab, "\t"), tk(tokenKindWord, "baz"), tk(tokenKindTab, "\t\t"), tk(tokenKindWord, "something"), } // ---- testing ---- if len(runes) != len(correctRunes) { test.Logf("len(runes) != len(correctRunes): %d, %d", len(runes), len(correctRunes)) test.Log(runes) test.Log(correctRunes) test.FailNow() } if !slices.Equal(runes, correctRunes) { test.Log("runes != correctRunes:") test.Log(runes) test.Log(correctRunes) test.FailNow() } if len(tokens) != len(correctTokens) { test.Logf("len(tokens) != len(correctTokens): %d, %d", len(tokens), len(correctTokens)) test.Log("GOT") logTokens(test, tokens) test.Log("CORRECT") logTokens(test, correctTokens) test.FailNow() } if !compareTokens(tokens, correctTokens) { test.Log("tokens != correctTokens:") test.Log("GOT") logTokens(test, tokens) test.Log("CORRECT") logTokens(test, correctTokens) test.FailNow() } test.Logf("changing first rune from %c to x", runes[0].run) runes[0].run = 'x' test.Logf("first rune is now %c", runes[0].run) tokenRune := tokens[0].runes[0].run if tokenRune != 'x' { test.Fatalf ( "tokens does not reference the same memory as runes after changing runes: %c, %c", runes[0].run, tokenRune) } runeIndex := 0 for tokenIndex, token := range tokens { tokenRunePtr := &token.runes[0] runePtr := &runes[runeIndex] if runePtr != tokenRunePtr { test.Fatalf ( "tokens[%d] does not reference runes[%d]: %p, %p", tokenIndex, runeIndex, tokenRunePtr, runePtr) } runeIndex += len(token.runes) } }