| 1 | package store |
| 2 | |
| 3 | import ( |
| 4 | "gorm.io/gorm" |
| 5 | |
| 6 | "amadan.net/oficina/sheets/internal/sheets/calc" |
| 7 | "amadan.net/oficina/sheets/internal/sheets/seal" |
| 8 | ) |
| 9 | |
| 10 | // Test-only seams, exported for package store_test. |
| 11 | // |
| 12 | // Three tests used to live in package store itself so they could reach |
| 13 | // these unexported names. They cannot any more: they migrate a database |
| 14 | // with sheets.BootSchema, and package sheets now imports this package — |
| 15 | // so an internal test file importing sheets is a cycle Go refuses. This |
| 16 | // file is the standard way out. It is a _test.go, so none of it exists |
| 17 | // in a built binary. |
| 18 | // |
| 19 | // The seams stay seams rather than becoming real API: what each of |
| 20 | // those tests proves is that the REAL code path does the right thing, |
| 21 | // and a test driving a parallel exported implementation would prove |
| 22 | // nothing about the one that ships. |
| 23 | |
| 24 | // EncodeValueForTest seals-encodes a computed value the way the handle |
| 25 | // does, so a fixture can plant a cache entry that looks like one a real |
| 26 | // recalculation wrote. |
| 27 | func EncodeValueForTest(v calc.Value) []byte { return encodeValue(v) } |
| 28 | |
| 29 | // BuildHandleForTest builds a handle without going through Open's |
| 30 | // refcounted registry, so a benchmark can time construction itself. |
| 31 | func BuildHandleForTest(db *gorm.DB, sealer *seal.Sealer, tabID uint64) (*Handle, error) { |
| 32 | return buildHandle(db, sealer, tabID) |
| 33 | } |
| 34 | |
| 35 | // TransitiveDependentsForTest reads the dependency graph directly, so a |
| 36 | // fixture can assert it really did wire more dependents than |
| 37 | // calc.MaxDirtyPerPass before exercising the over-cap path. |
| 38 | func TransitiveDependentsForTest(h *Handle, k calc.CellKey) map[calc.CellKey]struct{} { |
| 39 | return h.graph.TransitiveDependents(k) |
| 40 | } |
| 41 | |
| 42 | // InterruptBlankAfterFirstTransaction replaces the seam setBlank calls |
| 43 | // between its two transactions, and returns a function that puts the |
| 44 | // production no-op back. It is what lets a test interrupt real |
| 45 | // Set/setBlank code exactly at the crash window, rather than |
| 46 | // hand-fabricating a database state that Open's recovery would know how |
| 47 | // to fix whether or not Set ever wrote it. |
| 48 | func InterruptBlankAfterFirstTransaction(f func() error) (restore func()) { |
| 49 | old := afterBlankTransactionOneCommits |
| 50 | afterBlankTransactionOneCommits = f |
| 51 | return func() { afterBlankTransactionOneCommits = old } |
| 52 | } |
| 53 | |