Browse Source

More db_test.

Steve Thielemann 2 years ago
parent
commit
7c83d1465f
4 changed files with 144 additions and 8 deletions
  1. 7 5
      db.go
  2. 127 2
      db_test.go
  3. 3 1
      space-ace.go
  4. 7 0
      ymd.go

+ 7 - 5
db.go

@@ -47,6 +47,7 @@ func (db *DBData) Close() {
 const LOCK_USERNAME = ""
 const LOCK_SETTING = "LOCK"
 const LOCK_CLEAR = "0"
+const LOCK_STALE = 60
 
 func (db *DBData) Create() {
 	var SQLLines []string = []string{
@@ -119,7 +120,7 @@ RetryLock:
 			var lockTime time.Time = time.Unix(unixtime, 0)
 			howOld = now.Sub(lockTime)
 			log.Printf("Lock %s [%0.2f seconds old]\n", result, howOld.Seconds())
-			if howOld.Seconds() > 60 {
+			if howOld.Seconds() > LOCK_STALE {
 				// Lock expired
 				log.Printf("Lock %s [%0.2f seconds old] -- Expiring\n", result, howOld.Seconds())
 				db.DB.Exec("UPDATE settings SET value=? WHERE username=? AND setting=? AND value=?;",
@@ -381,16 +382,17 @@ func (db *DBData) GetScoresOnDay(date int64) []ScoresDetails {
 }
 
 type ScoresData struct {
-	Date  int64
+	Date  YMD
 	User  string
 	Score int
+	Run   int
 	Won   int
 }
 
 func (db *DBData) GetScores(limit int) []ScoresData {
 	var result []ScoresData
 
-	rows, err := db.DB.Query("SELECT date, username, SUM(score), SUM(won) "+
+	rows, err := db.DB.Query("SELECT date, username, SUM(score), MAX(run), SUM(won) "+
 		"FROM SCORES GROUP BY date, username ORDER BY SUM(score) DESC LIMIT ?;",
 		limit)
 	if err != nil {
@@ -402,7 +404,7 @@ func (db *DBData) GetScores(limit int) []ScoresData {
 	for rows.Next() {
 		var sd ScoresData
 
-		if err := rows.Scan(&sd.Date, &sd.User, &sd.Score, &sd.Won); err != nil {
+		if err := rows.Scan(&sd.Date, &sd.User, &sd.Score, &sd.Run, &sd.Won); err != nil {
 			log.Println("GetScores Scan", err)
 			return result
 		}
@@ -416,7 +418,7 @@ func (db *DBData) GetScores(limit int) []ScoresData {
 }
 
 type MonthlyData struct {
-	Date      int64
+	Date      YMD
 	User      string
 	Days      int
 	Hands_Won int

+ 127 - 2
db_test.go

@@ -1,12 +1,79 @@
 package main
 
 import (
+	"fmt"
 	"os"
 	"testing"
+	"time"
 )
 
 const DEBUG_DB bool = false
 
+func TestLock(t *testing.T) {
+	const testdb = ".space-settings.db"
+
+	db := DBData{}
+	// Start with empty database
+	os.Remove(testdb)
+
+	db.Open(testdb)
+	defer db.Close()
+	if !DEBUG_DB {
+		defer os.Remove(testdb)
+	}
+	db.User = LOCK_USERNAME
+	when := time.Now().Add(-time.Hour).Unix()
+	var oldLock string = fmt.Sprintf("%d,%d", os.Getpid(), when)
+	db.SetSetting(LOCK_SETTING, oldLock)
+	b := db.Lock(1)
+	if !b {
+		t.Error("Failed to get lock (time on lock expired).")
+	}
+}
+
+func TestSettings(t *testing.T) {
+	const testdb = ".space-settings.db"
+
+	db := DBData{}
+	// Start with empty database
+	os.Remove(testdb)
+
+	db.Open(testdb)
+	defer db.Close()
+	if !DEBUG_DB {
+		defer os.Remove(testdb)
+	}
+
+	users := []string{"test", "bob", "fish"}
+	settings := map[string]string{
+		"LastPlayed": "20200101",
+		"Deck":       "green",
+		"Rabbit":     "carrot",
+	}
+
+	for _, user := range users {
+		db.User = user
+		for key, value := range settings {
+			db.SetSetting(key, value)
+		}
+	}
+
+	for _, user := range users {
+		db.User = user
+		for key, value := range settings {
+			found := db.GetSetting(key, "?")
+			if found != value {
+				t.Errorf("Settings %s/%s: got %s, expected %s\n",
+					user, key, found, value)
+			}
+		}
+		found := db.GetSetting("missing", "ok")
+		if found != "ok" {
+			t.Errorf("Default %s: expected ok, got %s\n", user, found)
+		}
+	}
+}
+
 // Test the db.ExpireScores
 func TestExpireScores(t *testing.T) {
 	const testdb = ".space-test.db"
@@ -21,6 +88,8 @@ func TestExpireScores(t *testing.T) {
 		defer os.Remove(testdb)
 	}
 
+	db.Unlock()
+
 	db.User = "Testing"
 
 	// stuff score data into database
@@ -34,10 +103,18 @@ func TestExpireScores(t *testing.T) {
 		score int
 	}
 
+	type TScore struct {
+		Score int
+		Run   int
+		Won   int
+	}
+
+	var scoredata map[YMD]TScore = make(map[YMD]TScore)
+
 	var data []TData = []TData{
 		{20230101, 20230101, 1, 0, 8, 750},
 		{20230101, 20230101, 2, 0, 8, 780},
-		{20230101, 20230101, 3, 1, 5, 980},
+		// {20230101, 20230101, 3, 1, 5, 980},
 		{20230101, 20230102, 1, 1, 9, 945},
 		{20230101, 20230102, 2, 1, 6, 985},
 		{20230101, 20230102, 3, 0, 10, 700},
@@ -57,6 +134,54 @@ func TestExpireScores(t *testing.T) {
 			best = data[idx].run
 		}
 		won += data[idx].won
+
+		w := data[idx].date
+		_, has := scoredata[w]
+		if !has {
+			scoredata[w] = TScore{}
+		}
+		sd, has := scoredata[w]
+
+		sd.Score += data[idx].score
+		sd.Won += data[idx].won
+		if sd.Run < data[idx].run {
+			sd.Run = data[idx].run
+		}
+
+		scoredata[w] = sd
+	}
+
+	played := db.WhenPlayed()
+	playdata := map[YMD]int{20230101: 2,
+		20230102: 3, 20230115: 3}
+
+	for k, v := range played {
+		if v != playdata[k] {
+			t.Errorf("WhenPlayed %d: expected %d, got %d\n",
+				k, playdata[k], v)
+		}
+	}
+
+	scores := db.GetScores(5)
+	// Verify this has the expected scores (pre-expire)
+
+	// t.Errorf("ScoreData: %#v\n", scoredata)
+	// t.Errorf("GetScores: %#v\n", scores)
+
+	for _, s := range scores {
+		sd, _ := scoredata[s.Date]
+		if sd.Score != s.Score {
+			t.Errorf("GetScores %d: Got score %d, expected %d\n",
+				s.Date, s.Score, sd.Score)
+		}
+		if sd.Won != s.Won {
+			t.Errorf("GetScores %d: Got Won %d, expected %d\n",
+				s.Date, s.Won, sd.Won)
+		}
+		if sd.Run != s.Run {
+			t.Errorf("GetScores %d: Got Run %d, expected %d\n",
+				s.Date, s.Run, sd.Run)
+		}
 	}
 
 	// Data loaded .. call Expire!
@@ -65,7 +190,7 @@ func TestExpireScores(t *testing.T) {
 	db.ExpireScores(next_month)
 
 	// 1. Verify the scores table is empty.
-	scores := db.GetScores(5)
+	scores = db.GetScores(5)
 
 	if len(scores) != 0 {
 		t.Errorf("Scores not empty after ExpireScores got %d expected 0.\n", len(scores))

+ 3 - 1
space-ace.go

@@ -412,8 +412,10 @@ func DisplayScores(Door *door.Door, db *DBData, config *map[string]string) {
 			door.ColorText("BOLD YELLOW ON BLUE"))
 
 		for idx := range monthly {
+			// What?
+			timeDate := ToTime(monthly[idx].Date).Unix()
 			var result string = fmt.Sprintf("%*s", -longest_month,
-				FormatDate(monthly[idx].Date, date_monthly))
+				FormatDate(timeDate, date_monthly))
 			result += " " + fmt.Sprintf("%*s", -(nick_len-1), monthly[idx].User)
 			result += fmt.Sprintf(" %d", monthly[idx].Score)
 			result += strings.Repeat(" ", W-len(result))

+ 7 - 0
ymd.go

@@ -65,6 +65,13 @@ func (d *YMD) YMD() (int, int, int) {
 	return i / 10000, (i / 100) % 100, i % 100
 }
 
+func (d *YMD) Time() time.Time {
+	var value int = int(*d)
+	return time.Date(value/10000,
+		time.Month((value/100)%100),
+		value%100, 2, 2, 2, 0, time.Local)
+}
+
 // Convert time.Time to DBDate
 func NewYMDFromTime(point time.Time) YMD {
 	return YMD(point.Year()*10000 +