| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package tokenize
-
- import "fmt"
- import "testing"
-
- func Test_tokenize(t *testing.T) {
- var test_cases = []struct {
- test_str string
- want_result tokenizeResult
- }{
-
- // emptiness
- {"", tokenizeResult{tokens: []string{}}},
-
- // unquoted whitespace
- {" ", tokenizeResult{tokens: []string{}}},
- {"\t", tokenizeResult{tokens: []string{}}},
- {"\n", tokenizeResult{tokens: []string{}}},
- {" \t\n", tokenizeResult{tokens: []string{}}},
- {" \tfoo", tokenizeResult{tokens: []string{"foo"}}},
- {"foo ", tokenizeResult{tokens: []string{"foo"}}},
- {"foo bar", tokenizeResult{tokens: []string{"foo", "bar"}}},
- {"foo\nbar", tokenizeResult{tokens: []string{"foo", "bar"}}},
- {"foo\tbar", tokenizeResult{tokens: []string{"foo", "bar"}}},
-
- // single quotes
- {"'", tokenizeResult{tokens: []string{}, code: tokenizeResultCodeMissingEndSingleQuote}},
- {"''", tokenizeResult{tokens: []string{""}}},
- {"fo''o", tokenizeResult{tokens: []string{"foo"}}},
- {"foo '' bar", tokenizeResult{tokens: []string{"foo", "", "bar"}}},
- {"foo 'and' bar", tokenizeResult{tokens: []string{"foo", "and", "bar"}}},
- {"foo '\\\t\n' bar", tokenizeResult{tokens: []string{"foo", "\\\t\n", "bar"}}},
- {"foo ' space bar '", tokenizeResult{tokens: []string{"foo", " space bar "}}},
- {"foo 'John \"Spaceman\" Doe'", tokenizeResult{tokens: []string{"foo", "John \"Spaceman\" Doe"}}},
-
- // double quotes
- {"\"", tokenizeResult{tokens: []string{}, code: tokenizeResultCodeMissingEndDoubleQuote}},
- {"\"\"", tokenizeResult{tokens: []string{""}}},
- {"fo\"\"o", tokenizeResult{tokens: []string{"foo"}}},
- {"foo \"\" bar", tokenizeResult{tokens: []string{"foo", "", "bar"}}},
- {"foo \"and\" bar", tokenizeResult{tokens: []string{"foo", "and", "bar"}}},
- {"foo \"\\\t\n\" bar", tokenizeResult{tokens: []string{"foo", "\\\t\n", "bar"}}},
- {"foo \" space bar \"", tokenizeResult{tokens: []string{"foo", " space bar "}}},
- {"foo \"Joe's lunch\"", tokenizeResult{tokens: []string{"foo", "Joe's lunch"}}},
-
- // lone backslash
- {"\\", tokenizeResult{tokens: []string{}, code: tokenizeResultCodeMissingEscapedCharacter}},
- {"\\\\", tokenizeResult{tokens: []string{"\\"}}},
- {"\\a", tokenizeResult{tokens: []string{"a"}}},
- {"\\?", tokenizeResult{tokens: []string{"?"}}},
- {"\\$", tokenizeResult{tokens: []string{"$"}}},
- {"\\ ", tokenizeResult{tokens: []string{" "}}},
- {"\\\t", tokenizeResult{tokens: []string{"\t"}}},
- {"\\\n", tokenizeResult{tokens: []string{"\n"}}},
- {"fo\\o", tokenizeResult{tokens: []string{"foo"}}},
- {"fo\\\\o", tokenizeResult{tokens: []string{"fo\\o"}}},
- {"foo \\ bar", tokenizeResult{tokens: []string{"foo", " bar"}}},
- {"foo \\\\ bar", tokenizeResult{tokens: []string{"foo", "\\", "bar"}}},
- {"foo \\'bar\\' baz", tokenizeResult{tokens: []string{"foo", "'bar'", "baz"}}},
-
- //
- }
- for _, tc := range test_cases {
- t.Run(fmt.Sprintf("%q", tc.test_str), func(t *testing.T) {
- have_result := tokenize(tc.test_str)
- if have_result.code != tc.want_result.code {
- t.Errorf("unexpected result .code: got %s, want %s in %v", have_result.code, tc.want_result.code, have_result)
- return
- }
- if have_result.err_loc != tc.want_result.err_loc {
- t.Errorf("unexpected result .err_loc: got %d, want %d in %v", have_result.err_loc, tc.want_result.err_loc, have_result)
- return
- }
- if len(have_result.tokens) != len(tc.want_result.tokens) {
- t.Errorf("unexpected number of result .tokens: got %d, want %d in %v", len(have_result.tokens), len(tc.want_result.tokens), have_result)
- return
- }
- for i := range have_result.tokens {
- if have_result.tokens[i] == tc.want_result.tokens[i] {
- continue
- }
- t.Errorf("unexpected token in result .tokens[%d]: got %q, want %q in %v", i, have_result.tokens[i], tc.want_result.tokens[i], have_result)
- return
- }
- })
- }
- }
-
- func Test_reader_tossUntilNeitherOf(t *testing.T) {
- var test_cases = []struct {
- test_startpos uint
- test_data string
- test_needles string
- want_endpos uint
- want_ok bool
- }{
- {0, "", "", 0, false},
- {0, "", "x", 0, false},
- {0, "", "xy", 0, false},
- {0, "x", "", 0, false},
- {0, "x", "x", 1, true},
- {0, "x", "xy", 1, true},
- {0, "x", "yx", 1, true},
- {0, "xa", "x", 1, true},
- {0, "xa", "xy", 1, true},
- {0, "xa", "yx", 1, true},
- {0, "xya", "x", 1, true},
- {0, "xya", "xy", 2, true},
- {0, "xya", "yx", 2, true},
- {1, "xxya", "x", 2, true},
- {1, "xxya", "xy", 3, true},
- {1, "xxya", "yx", 3, true},
- }
- for _, tc := range test_cases {
- t.Run(fmt.Sprintf("%q[%d:]-%q", tc.test_data, tc.test_startpos, tc.test_needles), func(t *testing.T) {
- test_reader := reader{data: tc.test_data}
- test_reader.pos = tc.test_startpos
- have_ok := test_reader.tossUntilNeitherOf(tc.test_needles)
- if test_reader.pos != tc.want_endpos {
- t.Errorf("unexpected position after toss: got %d, want %d", test_reader.pos, tc.want_endpos)
- return
- }
- if have_ok != tc.want_ok {
- t.Errorf("unexpected ok: got %v, want %v", have_ok, tc.want_ok)
- return
- }
- })
- }
- }
|