Skip to content
quarry Artifact [a8be27726f]
Login

Artifact [a8be27726f]

Artifact a8be27726fcd81b346b7c5d65218946a4d52050351422551805ce144fa5c9781:


package index

import (
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/artifact"
)

// Every ticket page asks for the tracker's field names (ticket.config)
// and its recorded numbers (ticket.get), and both are scans of every
// ticket_field row: about 280ms on tcl's 300k rows, per render, for
// answers that only move when a fold does. So they are kept per fold
// generation. The proof that the answer is memoized is a row written
// behind the fold's back: it is not seen until a fold lands, and then
// it is.
func TestTheTrackerCensusIsKeptUntilAFold(t *testing.T) {
	ix := openIndex(t)
	tkt := func(n byte, fields ...artifact.Field) Parsed {
		return Parsed{Hash: strings.Repeat(string([]byte{'c', n}), 20),
			Art: &artifact.Artifact{Type: artifact.Ticket, TicketID: strings.Repeat(string([]byte{'a', n}), 20),
				Date: "2026-08-15T10:00:00", User: "dan", Fields: fields}}
	}
	if err := ix.FoldNow([]Parsed{tkt('1', artifact.Field{Name: "title", Value: "one"},
		artifact.Field{Name: "number", Value: "7"})}); err != nil {
		t.Fatal(err)
	}
	names := func() map[string]int {
		uses, err := ix.TicketFieldNames()
		if err != nil {
			t.Fatal(err)
		}
		out := map[string]int{}
		for _, u := range uses {
			out[u.Name] = u.Tickets
		}
		return out
	}
	numbers := func() map[string]int {
		n, err := ix.TicketRecordedNumbers()
		if err != nil {
			t.Fatal(err)
		}
		return n
	}
	if names()["title"] != 1 || numbers()[strings.Repeat("a1", 20)] != 7 {
		t.Fatalf("FAIL: first read names=%v numbers=%v", names(), numbers())
	}
	// A caller that edits what it was handed must not edit the memo.
	numbers()[strings.Repeat("a1", 20)] = 99
	if numbers()[strings.Repeat("a1", 20)] != 7 {
		t.Fatal("FAIL: a caller's edit reached the memoized numbers")
	}
	if _, err := ix.w.Exec(`INSERT INTO ticket_field (hash, name, value) VALUES (?, 'assignee', 'dan'), (?, 'number', '8')`,
		strings.Repeat("c1", 20)+"x", strings.Repeat("c1", 20)+"y"); err != nil {
		t.Fatal(err)
	}
	if _, ok := names()["assignee"]; ok {
		t.Fatal("FAIL: the field names were scanned again without a fold")
	}
	if err := ix.FoldNow([]Parsed{tkt('2', artifact.Field{Name: "title", Value: "two"},
		artifact.Field{Name: "number", Value: "9"})}); err != nil {
		t.Fatal(err)
	}
	if names()["assignee"] != 1 || names()["title"] != 2 {
		t.Fatalf("FAIL: a fold did not refresh the field names: %v", names())
	}
	if numbers()[strings.Repeat("a2", 20)] != 9 {
		t.Fatalf("FAIL: a fold did not refresh the recorded numbers: %v", numbers())
	}
	t.Log("ok: field names and recorded numbers are scanned once per fold and copied out")
}