func TestUnmarshalNullDate(t *testing.T) { var jsonNull string = `null` var jsonEmpty string = `""` var stringDate string = `"2010-07-03"` var stringTime string = `"2010-07-03T13:24:33"` var stringBogus string = `"bogus"` var n Date var err error err = json.Unmarshal([]byte(jsonNull), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(jsonEmpty), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(stringDate), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Date.Year, 2010) expect.Equal(t, n.Date.Month, time.July) expect.Equal(t, n.Date.Day, 3) err = json.Unmarshal([]byte(stringTime), &n) expect.NotNil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(stringBogus), &n) expect.NotNil(t, err) expect.False(t, n.Valid) }
func TestUnmarshalNullString(t *testing.T) { var jsonNull string = `null` var jsonNumber string = `3` var jsonEmpty string = `""` var validString string = `"foo"` var n String var err error err = json.Unmarshal([]byte(jsonNull), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(jsonNumber), &n) expect.NotNil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(jsonEmpty), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.String, "") err = json.Unmarshal([]byte(validString), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.String, "foo") }
func TestUnmarshalNullTime(t *testing.T) { var jsonNull string = `null` var jsonEmpty string = `""` var stringTime string = `"2010-07-03T13:24:33Z"` var stringBogus string = `"bogus"` var n Time var err error err = json.Unmarshal([]byte(jsonNull), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(jsonEmpty), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(stringTime), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Time.Format("2006-01-02 15:04:05"), "2010-07-03 13:24:33") err = json.Unmarshal([]byte(stringBogus), &n) expect.NotNil(t, err) expect.False(t, n.Valid) }
func TestTraceParser(t *testing.T) { output := bytes.Buffer{} parser := New([]byte(`SELECT * FROM table_with_long_name WHERE ♫`), Ruleset{}) parser.Trace = &output stmt, err := parser.ParseStatement() expect.NotNil(t, err, "expected a parsing error") expect.Nil(t, stmt) expected := []string{ regexp.QuoteMeta(` SELECT : SELECT @ Parser.parseSelect:`) + "[0-9]+", regexp.QuoteMeta(` : * @ Parser.parseSelect:`) + "[0-9]+", regexp.QuoteMeta(` FROM : FROM @ Parser.parseSelect:`) + "[0-9]+", regexp.QuoteMeta(` table_~ : Identifier @ Parser.parseSelect:`) + "[0-9]+", regexp.QuoteMeta(` WHERE : WHERE @ Parser.parseSelect:`) + "[0-9]+", regexp.QuoteMeta(` (error) sql:1:42: unexpected character U+266B '♫'`), "$", // string ends with newline } // compare trace output, ignoring the source line numbers lines := strings.Split(output.String(), "\n") if expect.Equal(t, len(lines), len(expected)) { maxSafe := utils.MinInt(len(expected), len(lines)) for i := 0; i < maxSafe; i++ { expect.Regexp(t, lines[i], "^"+expected[i]) } } else { t.Log("Error:", err) t.Log("Full trace output:\n", output.String()) } }
func TestUnmarshalNullBool(t *testing.T) { var jsonNull string = `null` var jsonEmpty string = `""` var bogusString string = `"bogus"` var validTrue string = `true` var validFalse string = `false` var n Bool var err error err = json.Unmarshal([]byte(jsonNull), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(jsonEmpty), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(bogusString), &n) expect.NotNil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(validTrue), &n) expect.Nil(t, err) expect.True(t, n.Valid) err = json.Unmarshal([]byte(validFalse), &n) expect.Nil(t, err) expect.True(t, n.Valid) }
func TestParseErrors(t *testing.T) { examples := []struct { Input string Error string }{ {Input: `mytable`, Error: `sql:1:8: expected 'SELECT, INSERT, or UPDATE' but received 'Identifier'`}, {Input: `SELECT * WHERE`, Error: `sql:1:15: expected 'FROM' but received 'WHERE'`}, {Input: `SELECT * FROM *`, Error: `sql:1:16: expected 'a table name' but received '*'`}, {Input: "SELECT `mycolumn` FROM mytable", // backticks (w/ ansi ruleset) Error: "sql:1:8: unexpected character U+0060 '`'"}, {Input: `SELECT DISTINCTROW * FROM mytable`, // distinctrow (w/ ansi ruleset) Error: `sql:1:19: statement includes SELECT "DISTINCTROW", but CanSelectDistinctRow is false`}, {Input: `~`, Error: `sql:1:1: unexpected character U+007E '~'`}, {Input: `SELECT * FROM foos; SELECT * FROM bars;`, Error: `sql:1:27: statement does not end at semicolon`}, {Input: `SELECT * FROM mytable PROCEDURE compute(foo)`, // with HasLiteral Error: `sql:1:32: cannot parse statement; reached unimplemented clause at 'PROCEDURE'`}, {Input: `SELECT * FROM mytable +`, // without HasLiteral Error: `sql:1:24: cannot parse statement; reached unimplemented clause at '+'`}, } for _, example := range examples { parser := New([]byte(example.Input), Ruleset{}) stmt, err := parser.ParseStatement() expect.Nil(t, stmt) if expect.NotNil(t, err, "expected a parsing error") { expect.Equal(t, err.Error(), example.Error) } } }
func TestScanNullTime(t *testing.T) { var rawTime = time.Now() var mysqlTime = "2010-07-03 13:24:33" var byteTime = []byte(mysqlTime) var notTime = 3 var n Time var err error err = n.Scan(rawTime) expect.Nil(t, err) expect.True(t, n.Valid) expect.NotEmpty(t, n.Time.Format("2006-01-02 15:04:05")) err = n.Scan(mysqlTime) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Time.Format("2006-01-02 15:04:05"), mysqlTime) err = n.Scan(byteTime) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Time.Format("2006-01-02 15:04:05"), mysqlTime) err = n.Scan(notTime) expect.NotNil(t, err) expect.False(t, n.Valid) }
func TestUnmarshalJSON(t *testing.T) { examples := []struct { Json string Version Version }{ {`"5.0.0"`, Version{5, 0, 0}}, {`"v2.4.12"`, Version{2, 4, 12}}, {`"3.5.0ab"`, Version{3, 5, 0}}, {`"8.22"`, Version{8, 22, 0}}, } var v Version for _, ex := range examples { err := json.Unmarshal([]byte(ex.Json), &v) expect.Nil(t, err, ex.Json) expect.Equal(t, v, ex.Version, ex.Json) } badExamples := []struct { Json string Error string }{ {`null`, "semver: cannot parse version from non-string JSON value"}, {`""`, "semver: json string is not a valid version"}, {`"bogus"`, "semver: json string is not a valid version"}, } for _, ex := range badExamples { err := json.Unmarshal([]byte(ex.Json), &v) if expect.NotNil(t, err, ex.Json) { expect.Equal(t, err.Error(), ex.Error, ex.Json) } } }
func TestParseUpdate(t *testing.T) { parser := New([]byte(`UPDATE mytable SET a = 1`), Ruleset{}) stmt, err := parser.ParseStatement() expect.Nil(t, stmt) if expect.NotNil(t, err) { expect.Equal(t, err.Error(), `sql:1:15: cannot parse statement; reached unimplemented clause at 'mytable'`) } }
func TestSqlParseError(t *testing.T) { db, err := sql.Open("sqltest", "") expect.Nil(t, err) _, err = db.Query("SELECT * FROM") expect.NotNil(t, err) expect.Equal(t, err.Error(), "sql:1:14: expected 'a table name' but received 'End of statement'") }
func TestParseInsert(t *testing.T) { parser := New([]byte(`INSERT INTO mytable`), Ruleset{}) stmt, err := parser.ParseStatement() expect.Nil(t, stmt) if expect.NotNil(t, err) { expect.Equal(t, err.Error(), `sql:1:20: cannot parse statement; reached unimplemented clause at 'mytable'`) } }
func TestReportsUsefulunknownCharacter(t *testing.T) { scan, err := scanOnce("\u203B") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, "unexpected character U+203B '\u203B'") } scan, err = scanOnce("\u200b") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unexpected character U+200B`) } }
func TestErrorsRespectWhitespace(t *testing.T) { scan, err := scanOnce("\n\n ~\n") expect.Equal(t, token.INVALID, scan.tok) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 6) expect.Equal(t, err.pos.Line, 3) expect.Equal(t, err.pos.Column, 5) expect.Equal(t, err.msg, `unexpected character U+007E '~'`) } }
func TestScanNullDate(t *testing.T) { var rawTime = time.Date(2010, time.July, 3, 13, 24, 33, 999, time.UTC) var mysqlTime = "2010-07-03 13:24:33" var mysqlDate = "2010-07-03" var byteTime = []byte(mysqlTime) var byteDate = []byte(mysqlDate) var notTime = 3 var n Date var err error err = n.Scan(rawTime) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Date.Year, 2010) expect.Equal(t, n.Date.Month, time.July) expect.Equal(t, n.Date.Day, 3) err = n.Scan(mysqlTime) expect.NotNil(t, err) expect.False(t, n.Valid) err = n.Scan(mysqlDate) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Date.Year, 2010) expect.Equal(t, n.Date.Month, time.July) expect.Equal(t, n.Date.Day, 3) err = n.Scan(byteTime) expect.NotNil(t, err) expect.False(t, n.Valid) err = n.Scan(byteDate) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Date.Year, 2010) expect.Equal(t, n.Date.Month, time.July) expect.Equal(t, n.Date.Day, 3) err = n.Scan(notTime) expect.NotNil(t, err) expect.False(t, n.Valid) }
func TestScannerNextCharacter(t *testing.T) { var err *scanError err = scanAll("SELECT * FROM candies\r\n WHERE sweetness = 11\n\r\r") expect.Nil(t, err) err = scanAll(string([]byte{0x00, 0xFF})) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unexpected character U+0000`) } }
func TestUnmarshalNullInt(t *testing.T) { var jsonNull string = `null` var rationalFloat string = `12.22` var roundedFloat string = `16.0` var validZero string = `0` var validNegative string = `-300` var validPositive string = `1602525` var n Int var err error err = json.Unmarshal([]byte(jsonNull), &n) expect.Nil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(rationalFloat), &n) expect.NotNil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(roundedFloat), &n) expect.NotNil(t, err) expect.False(t, n.Valid) err = json.Unmarshal([]byte(validZero), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Int, 0) err = json.Unmarshal([]byte(validNegative), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Int, -300) err = json.Unmarshal([]byte(validPositive), &n) expect.Nil(t, err) expect.True(t, n.Valid) expect.Equal(t, n.Int, 1602525) }
func TestReportsUsefulNumberErrors(t *testing.T) { scan, err := scanOnce("1.") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `missing digits after decimal point in number`) } scan, err = scanOnce("1.A") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `missing digits after decimal point in number`) } scan, err = scanOnce("1.0e") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `missing digits after exponent in number`) } scan, err = scanOnce("1.0eA") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `missing digits after exponent in number`) } }
func TestImplementsJsonUnmarshaller(t *testing.T) { var unmarshaler json.Unmarshaler unmarshaler = &Date{} expect.NotNil(t, unmarshaler) unmarshaler = &Time{} expect.NotNil(t, unmarshaler) unmarshaler = &String{} expect.NotNil(t, unmarshaler) unmarshaler = &Int{} expect.NotNil(t, unmarshaler) unmarshaler = &Bool{} expect.NotNil(t, unmarshaler) unmarshaler = &UUID{} expect.NotNil(t, unmarshaler) }
func TestImplementsSqlValuer(t *testing.T) { var valuer driver.Valuer valuer = Date{} expect.NotNil(t, valuer) valuer = Time{} expect.NotNil(t, valuer) valuer = String{} expect.NotNil(t, valuer) valuer = Int{} expect.NotNil(t, valuer) valuer = Bool{} expect.NotNil(t, valuer) valuer = UUID{} expect.NotNil(t, valuer) }
func TestImplementsJsonMarshaller(t *testing.T) { var marshaler json.Marshaler marshaler = Date{} expect.NotNil(t, marshaler) marshaler = Time{} expect.NotNil(t, marshaler) marshaler = String{} expect.NotNil(t, marshaler) marshaler = Int{} expect.NotNil(t, marshaler) marshaler = Bool{} expect.NotNil(t, marshaler) marshaler = UUID{} expect.NotNil(t, marshaler) }
func TestImplementSqlScanner(t *testing.T) { var scanner sql.Scanner scanner = &Date{} expect.NotNil(t, scanner) scanner = &Time{} expect.NotNil(t, scanner) scanner = &String{} expect.NotNil(t, scanner) scanner = &Int{} expect.NotNil(t, scanner) scanner = &Bool{} expect.NotNil(t, scanner) scanner = &UUID{} expect.NotNil(t, scanner) }
func TestReportsUsefulStringErrors(t *testing.T) { scan, err := scanOnce(`'`) expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unterminated string`) } scan, err = scanOnce(`'No end quote`) expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unterminated string`) } // scan, err = scanOnce("'contains unescaped \u0007 control char'") // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 0) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 1) // expect.Equal(t, err.msg, `unexpected character in string: U+0007`) // } // scan, err = scanOnce("'null-byte \u0000 in string'") // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 0) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 1) // expect.Equal(t, err.msg, `unexpected character in string: U+0000`) // } // scan, err = scanOnce(`'\u`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 2) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 3) // expect.Equal(t, err.msg, `unterminated escape sequence`) // } // scan, err = scanOnce(`'\`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 2) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 3) // expect.Equal(t, err.msg, `unterminated escape sequence`) // } // scan, err = scanOnce(`'\m'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 2) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 3) // expect.Equal(t, err.msg, `unknown escape sequence`) // } // scan, err = scanOnce(`'\uD800'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 2) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 3) // expect.Equal(t, err.msg, `escape sequence is invalid unicode code point`) // } scan, err = scanOnce("'multi\nline'") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unterminated string`) } scan, err = scanOnce("'multi\rline'") expect.Equal(t, scan.tok, token.INVALID) if expect.NotNil(t, err) { expect.Equal(t, err.pos.Offset, 0) expect.Equal(t, err.pos.Line, 1) expect.Equal(t, err.pos.Column, 1) expect.Equal(t, err.msg, `unterminated string`) } // scan, err = scanOnce(`'bad \z esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character escape sequence: \z`) // } // scan, err = scanOnce(`'bad \x esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character escape sequence: \x`) // } // scan, err = scanOnce(`'bad \u1 esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character in escape sequence: U+0020 ' '`) // } // scan, err = scanOnce(`'bad \u0XX1 esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character in escape sequence: U+0058 'X'`) // } // scan, err = scanOnce(`'bad \uXXXX esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character in escape sequence: U+0058 'X'`) // } // scan, err = scanOnce(`'bad \uFXXX esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character in escape sequence: U+0058 'X'`) // } // scan, err = scanOnce(`'bad \uXXXF esc'`) // expect.Equal(t, scan.tok, token.INVALID) // if expect.NotNil(t, err) { // expect.Equal(t, err.pos.Offset, 6) // expect.Equal(t, err.pos.Line, 1) // expect.Equal(t, err.pos.Column, 7) // expect.Equal(t, err.msg, `unexpected character in escape sequence: U+0058 'X'`) // } }