diff --git a/btreeindex_test.go b/btreeindex_test.go index 8ad7da7..0de492c 100644 --- a/btreeindex_test.go +++ b/btreeindex_test.go @@ -43,8 +43,6 @@ func TestFullBTreeIndex(t *testing.T) { return users }) - // Update - run("update", func(t *testing.T, db *DB) (users []*User) { users = append(users, &User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"}, @@ -120,14 +118,117 @@ func TestFullBTreeIndex(t *testing.T) { } func TestPartialBTreeIndex(t *testing.T) { - // empty - // insert into - // insert outside - // upate out to in - // update out to out - // update in to in - // update in to out - // delete outside - // delete in - // load w/duplicate + + // Test against the name index. + run := func(name string, inner func(t *testing.T, db *DB) []*User) { + testWithDB(t, name, func(t *testing.T, db *DB) { + expected := inner(t, db) + + if err := db.Users.nameBTree.EqualsList(expected); err != nil { + t.Fatal(err) + } + + db.Close() + db = OpenDB(db.root, true) + + if err := db.Users.nameBTree.EqualsList(expected); err != nil { + t.Fatal(err) + } + }) + } + + run("empty", func(t *testing.T, db *DB) []*User { + return []*User{} + }) + + run("insert", func(t *testing.T, db *DB) (users []*User) { + users = append(users, + &User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"}, + &User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg"}, + &User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "aaa"}) + + for _, u := range users { + if _, err := db.Users.c.Insert(*u); err != nil { + t.Fatal(err) + } + } + users[0], users[2] = users[2], users[0] + + return users + }) + + run("insert duplicates", func(t *testing.T, db *DB) (users []*User) { + users = append(users, + &User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "xxx"}, + &User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ggg"}, + &User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "xxx"}) + + for _, u := range users { + if _, err := db.Users.c.Insert(*u); err != nil { + t.Fatal(err) + } + } + users = []*User{users[1], users[0], users[2]} + return users + }) + + run("update", func(t *testing.T, db *DB) (users []*User) { + users = append(users, + &User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "ccc"}, + &User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "aaa"}, + &User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "bbb"}) + + for _, u := range users { + if _, err := db.Users.c.Insert(*u); err != nil { + t.Fatal(err) + } + } + + err := db.Users.c.Update(users[1].ID, func(u User) (User, error) { + u.Name = "ccc" + return u, nil + }) + if err != nil { + t.Fatal(err) + } + users[1].Name = "ccc" + + users = []*User{users[2], users[0], users[1]} + return users + }) + + run("update", func(t *testing.T, db *DB) (users []*User) { + users = append(users, + &User{ID: db.Users.c.NextID(), Email: "a@b.com", Name: "bbb"}, + &User{ID: db.Users.c.NextID(), Email: "c@d.com", Name: "aaa"}, + &User{ID: db.Users.c.NextID(), Email: "e@f.com", Name: "bbb"}) + + for _, u := range users { + if _, err := db.Users.c.Insert(*u); err != nil { + t.Fatal(err) + } + } + + db.Users.c.Delete(users[1].ID) + users = []*User{users[0], users[2]} + return users + }) +} + +func TestBTreeIndex_load_ErrDuplicate(t *testing.T) { + testWithDB(t, "", func(t *testing.T, db *DB) { + idx := NewBTreeIndex( + db.Users.c, + func(lhs, rhs *User) bool { return lhs.ExtID < rhs.ExtID }, + nil) + + users := map[uint64]*User{ + 1: {ID: 1, Email: "x@y.com", Name: "xx", ExtID: "x"}, + 2: {ID: 2, Email: "a@b.com", Name: "aa", ExtID: "x"}, + } + + if err := idx.load(users); err != ErrDuplicate { + t.Fatal(err) + } + }) } diff --git a/btreeiterator_test.go b/btreeiterator_test.go new file mode 100644 index 0000000..6f3612e --- /dev/null +++ b/btreeiterator_test.go @@ -0,0 +1,42 @@ +package mdb + +import ( + "reflect" + "testing" +) + +func TestBTreeIterator(t *testing.T) { + testWithDB(t, "min/max matches iterator", func(t *testing.T, db *DB) { + users := []User{ + {ID: db.Users.c.NextID(), Email: "a@b.com", Name: "aaa"}, + {ID: db.Users.c.NextID(), Email: "e@f.com", Name: "bbb"}, + {ID: db.Users.c.NextID(), Email: "c@d.com", Name: "ccc"}, + } + for _, u := range users { + if _, err := db.Users.c.Insert(u); err != nil { + t.Fatal(err) + } + } + + it := db.Users.nameBTree.Ascend() + if !it.Next() { + t.Fatal("No next") + } + u := it.Value() + if !reflect.DeepEqual(u, users[0]) { + t.Fatal(u, users[0]) + } + it.Close() + + it = db.Users.nameBTree.Descend() + if !it.Next() { + t.Fatal("No next") + } + u = it.Value() + if !reflect.DeepEqual(u, users[2]) { + t.Fatal(u, users[2]) + } + it.Close() + + }) +}