package papod_test import ( "bufio" "database/sql" "errors" "reflect" "strings" "testing" g "euandre.org/gobang/src" "euandre.org/papod/src" // "fmt" ) func errorIf(t *testing.T, err error) { if err != nil { t.Errorf("Unexpected error: %#v\n", err) } } func assertEqual(t *testing.T, given any, expected any) { if !reflect.DeepEqual(given, expected) { t.Errorf("given != expected\n") t.Errorf("given: %#v\n", given) t.Errorf("expected: %#v\n", expected) } } func assertEqualI(t *testing.T, i int, given any, expected any) { if !reflect.DeepEqual(given, expected) { t.Errorf("given != expected (i = %d)\n", i) t.Errorf("given: %#v\n", given) t.Errorf("expected: %#v\n", expected) } } func TestSplitOnCRLF(t *testing.T) { type tableT struct { input string expected []string } table := []tableT { { "", nil, }, { "\r\n", []string { "" }, }, { "abc\r\n", []string { "abc" }, }, { "abc\r\n ", []string { "abc" }, }, { "abc\r\n \r\n", []string { "abc", " " }, }, { " \r\n \r\n", []string { " ", " " }, }, { "aaa\r\nbbb\r\nccc\r\n", []string { "aaa", "bbb", "ccc" }, }, { "\r\nsplit \r \n CRLF\r\n\r\n", []string { "", "split \r \n CRLF", "" }, }, } for i, entry := range table { var given []string scanner := bufio.NewScanner(strings.NewReader(entry.input)) scanner.Split(papod.SplitOnCRLF) for scanner.Scan() { given = append(given, scanner.Text()) } err := scanner.Err() errorIf(t, err) assertEqualI(t, i, given, entry.expected) } } func TestSplitOnRawMessage(t *testing.T) { type tableT struct { input string expected []string } table := []tableT { { "first message\r\nsecond message\r\n", []string { "first message", "second message" }, }, { "message 1\r\n\r\nmessage 2\r\n\r\nignored", []string { "message 1", "message 2" }, }, } for i, entry := range table { var given []string scanner := bufio.NewScanner(strings.NewReader(entry.input)) scanner.Split(papod.SplitOnRawMessage) for scanner.Scan() { given = append(given, scanner.Text()) } err := scanner.Err() errorIf(t, err) assertEqualI(t, i, given, entry.expected) } } func TestParseMessageParams(t *testing.T) { type tableT struct { input string expected papod.MessageParams } table := []tableT { { "", papod.MessageParams { Middle: []string { }, Trailing: "", }, }, { " ", papod.MessageParams { Middle: []string { }, Trailing: "", }, }, { " :", papod.MessageParams { Middle: []string { }, Trailing: "", }, }, { " : ", papod.MessageParams { Middle: []string { }, Trailing: " ", }, }, { ": ", papod.MessageParams { Middle: []string { ":" }, Trailing: "", }, }, { ": ", papod.MessageParams { Middle: []string { ":" }, Trailing: "", }, }, { " : ", papod.MessageParams { Middle: []string { }, Trailing: " ", }, }, { " :", papod.MessageParams { Middle: []string { }, Trailing: "", }, }, { " :", papod.MessageParams { Middle: []string { }, Trailing: "", }, }, { "a", papod.MessageParams { Middle: []string { "a" }, Trailing: "", }, }, { "ab", papod.MessageParams { Middle: []string { "ab" }, Trailing: "", }, }, { "a b", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: "", }, }, { "a b c", papod.MessageParams { Middle: []string { "a", "b", "c" }, Trailing: "", }, }, { "a b:c", papod.MessageParams { Middle: []string { "a", "b:c" }, Trailing: "", }, }, { "a b:c:", papod.MessageParams { Middle: []string { "a", "b:c:" }, Trailing: "", }, }, { "a b :c", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: "c", }, }, { "a b :c:", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: "c:", }, }, { "a b :c ", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: "c ", }, }, { "a b : c", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c", }, }, { "a b : c ", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c ", }, }, { "a b : c :", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c :", }, }, { "a b : c : ", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c : ", }, }, { "a b : c :d", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c :d", }, }, { "a b : c :d ", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c :d ", }, }, { "a b : c : d ", papod.MessageParams { Middle: []string { "a", "b" }, Trailing: " c : d ", }, }, } for i, entry := range table { given := papod.ParseMessageParams(entry.input) assertEqualI(t, i, given, entry.expected) } } func TestParseMessage(t *testing.T) { type tableTOK struct { input string expected papod.Message } tableOK := []tableTOK { { "NICK joebloe ", papod.Message { Prefix: "", Command: "NICK", Params: papod.MessageParams { Middle: []string { "joebloe" }, Trailing: "", }, Raw: "NICK joebloe ", }, }, { "USER joebloe 0.0.0.0 joe :Joe Bloe", papod.Message { Prefix: "", Command: "USER", Params: papod.MessageParams { Middle: []string { "joebloe", "0.0.0.0", "joe", }, Trailing: "Joe Bloe", }, Raw: "USER joebloe 0.0.0.0 joe :Joe Bloe", }, }, { ":pre USER joebloe 0.0.0.0 joe :Joe Bloe", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { "joebloe", "0.0.0.0", "joe", }, Trailing: "Joe Bloe", }, Raw: ":pre USER joebloe 0.0.0.0 joe :Joe Bloe", }, }, { ":pre USER joebloe 0.0.0.0 joe : Joe Bloe ", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { "joebloe", "0.0.0.0", "joe", }, Trailing: " Joe Bloe ", }, Raw: ":pre USER joebloe 0.0.0.0 joe : Joe Bloe ", }, }, { ":pre USER joebloe: 0:0:0:0 joe::a: : Joe Bloe ", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { "joebloe:", "0:0:0:0", "joe::a:", }, Trailing: " Joe Bloe ", }, Raw: ":pre USER joebloe: 0:0:0:0 joe::a: : Joe Bloe ", }, }, { ":pre USER :Joe Bloe", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { }, Trailing: "Joe Bloe", }, Raw: ":pre USER :Joe Bloe", }, }, { ":pre USER : Joe Bloe", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { }, Trailing: " Joe Bloe", }, Raw: ":pre USER : Joe Bloe", }, }, { ":pre USER : Joe Bloe", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { }, Trailing: " Joe Bloe", }, Raw: ":pre USER : Joe Bloe", }, }, { ":pre USER : ", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { }, Trailing: " ", }, Raw: ":pre USER : ", }, }, { ":pre USER :", papod.Message { Prefix: "pre", Command: "USER", Params: papod.MessageParams { Middle: []string { }, Trailing: "", }, Raw: ":pre USER :", }, }, } for i, entry := range tableOK { given, err := papod.ParseMessage(entry.input) errorIf(t, err) assertEqualI(t, i, given, entry.expected) } type tableErrorT struct { input string expected error } parseErr := errors.New("Can't parse message") tableError := []tableErrorT { { ":pre", parseErr, }, { ": pre", parseErr, }, { ":pre N1CK", parseErr, }, } for i, entry := range tableError { _, given := papod.ParseMessage(entry.input) assertEqualI(t, i, given, entry.expected) } } func TestInitMigrations(t *testing.T) { const query = `SELECT filename FROM migrations;` db, err := sql.Open("sqlite3", ":memory:") g.FatalIf(err) _, err = db.Query(query) assertEqual(t, err.Error(), "no such table: migrations") for i := 0; i < 5; i++ { papod.InitMigrations(db) rows, err := db.Query(query) g.FatalIf(err) assertEqual(t, rows.Next(), false) g.FatalIf(rows.Err()) } } func TestPendingMigrations(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") g.FatalIf(err) papod.InitMigrations(db) pending1 := papod.PendingMigrations(db) pending2 := papod.PendingMigrations(db) assertEqual(t, pending1, pending2) } func TestRunMigrations(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") g.FatalIf(err) for i := 0; i < 5; i++ { papod.RunMigrations(db) } }