package lexer import ( "reflect" "testing" ) func TestLexer(t *testing.T) { type testCase struct { input string expect []string expectErr bool } cases := []testCase{ testCase{ input: "foo bar baz", expect: []string{"foo", "bar", "baz"}, expectErr: false, }, // Quotes testCase{ input: `foo "bar" baz`, expect: []string{"foo", `"bar"`, "baz"}, expectErr: false, }, testCase{ input: `foo "bar baz" quux`, expect: []string{"foo", `"bar baz"`, "quux"}, expectErr: false, }, testCase{ input: `foo 'bar baz' quux`, expect: []string{"foo", `'bar baz'`, "quux"}, expectErr: false, }, // Escape characters testCase{ input: `foo 'bar \n baz' quux`, expect: []string{"foo", `'bar \n baz'`, "quux"}, expectErr: false, }, testCase{ input: `foo "bar\"" baz`, expect: []string{"foo", `"bar\""`, "baz"}, expectErr: false, }, // Collapsing whitespace testCase{ input: " foo bar \r\t\n baz\n", expect: []string{"foo", "bar", "baz"}, expectErr: false, }, // Special characters lexed as separate tokens, but only at top level testCase{ input: `3+5*(2.3/6);`, expect: []string{"3", `+`, "5", "*", "(", "2.3", "/", "6", ")", ";"}, expectErr: false, }, testCase{ input: `SELECT "3+5*(2.3/6)" AS expression;`, expect: []string{"SELECT", `"3+5*(2.3/6)"`, "AS", "expression", ";"}, expectErr: false, }, testCase{ input: `INSERT INTO foo (bar, baz) VALUES (?, ?);`, expect: []string{"INSERT", "INTO", "foo", "(", "bar", ",", "baz", ")", "VALUES", "(", "?", ",", "?", ")", ";"}, expectErr: false, }, // Errors testCase{ input: `foo "bar`, expect: nil, expectErr: true, // mismatched quotes }, testCase{ input: `foo 'bar`, expect: nil, expectErr: true, // mismatched quotes }, testCase{ input: `foo \"bar"`, expect: nil, expectErr: true, // invalid top-level escape }, testCase{ input: `foo "bar\ "`, expect: nil, expectErr: true, // escaping nothing }, } for _, tc := range cases { out, err := Fields(tc.input) if err != nil { if !tc.expectErr { t.Errorf("Test %q got error %v, expected nil", tc.input, err) } } else { if tc.expectErr { t.Errorf("Test %q got error , expected error", tc.input) continue } if !reflect.DeepEqual(out, tc.expect) { t.Errorf("Test %q\n- got: %#v\n- expected %#v", tc.input, out, tc.expect) } } } }