package oltp
import (
"path/filepath"
"testing"
)
func stampDB(t *testing.T) *DB {
t.Helper()
db, err := Open(filepath.Join(t.TempDir(), "oltp.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { db.Close() })
return db
}
func TestStampIsOnePerAccountPerRepo(t *testing.T) {
db := stampDB(t)
if db.Stamped("alpha", "dan") {
t.Error("stamped before anyone stamped")
}
for i := 0; i < 3; i++ {
if on, err := db.SetStamp("alpha", "dan", true); err != nil || !on {
t.Fatalf("stamp: %v %v", on, err)
}
}
if n := db.StampCount("alpha"); n != 1 {
t.Errorf("count = %d after praising three times; the key is the idempotency", n)
}
if _, err := db.SetStamp("alpha", "eve", true); err != nil {
t.Fatal(err)
}
if n := db.StampCount("alpha"); n != 2 {
t.Errorf("count = %d, want 2", n)
}
// Withdrawing is a delete, and only the withdrawer's.
if on, err := db.SetStamp("alpha", "dan", false); err != nil || on {
t.Fatalf("withdraw: %v %v", on, err)
}
if db.Stamped("alpha", "dan") {
t.Error("still stamped after withdrawing")
}
if !db.Stamped("alpha", "eve") {
t.Error("withdrawing took someone else's stamp with it")
}
if n := db.StampCount("alpha"); n != 1 {
t.Errorf("count = %d, want 1", n)
}
}
// Re-praising must not move the date, or a listing ordered by when you
// stamped something reshuffles on a double-click.
func TestRestampKeepsItsPlace(t *testing.T) {
db := stampDB(t)
for _, repo := range []string{"alpha", "beta", "gamma"} {
if _, err := db.SetStamp(repo, "dan", true); err != nil {
t.Fatal(err)
}
}
first, err := db.StampedBy("dan")
if err != nil {
t.Fatal(err)
}
if _, err := db.SetStamp("alpha", "dan", true); err != nil {
t.Fatal(err)
}
again, _ := db.StampedBy("dan")
if len(first) != 3 || len(again) != 3 {
t.Fatalf("listing lengths %d then %d, want 3", len(first), len(again))
}
for i := range first {
if first[i] != again[i] {
t.Fatalf("re-praising reordered the list: %v then %v", first, again)
}
}
}
func TestStampedByIsPerAccount(t *testing.T) {
db := stampDB(t)
db.SetStamp("alpha", "dan", true)
db.SetStamp("beta", "eve", true)
dan, _ := db.StampedBy("dan")
if len(dan) != 1 || dan[0] != "alpha" {
t.Errorf("dan stamps %v, want [alpha]", dan)
}
if got, _ := db.StampedBy("nobody"); len(got) != 0 {
t.Errorf("an account that stamped nothing lists %v", got)
}
}
func TestStampRefusesAnUnnamedSubject(t *testing.T) {
db := stampDB(t)
if _, err := db.SetStamp("", "dan", true); err == nil {
t.Error("stamped no repository")
}
if _, err := db.SetStamp("alpha", "", true); err == nil {
t.Error("stamped as nobody — stamp must be attributable")
}
}