1package vt
2
3import (
4 "testing"
5
6 "github.com/bnema/vev/pkg/renderer"
7 "github.com/stretchr/testify/require"
8)
9
10func TestHistorySnapshotViewDoesNotSealTailAndCopiesIt(t *testing.T) {
11 history := NewHistory(HistoryConfig{MaxRows: 8, ChunkRows: 2})
12 requireHistoryAppend(t, history, historyRow("AAAA"))
13 requireHistoryAppend(t, history, historyRow("BBBB"))
14 requireHistoryAppend(t, history, historyRow("CCCC"))
15 sealed := history.View().Chunk(0)
16
17 view := history.SnapshotView()
18 if got, want := view.ChunkCount(), 1; got != want {
19 t.Fatalf("sealed chunks = %d, want %d", got, want)
20 }
21 if view.Chunk(0) != sealed {
22 t.Fatal("snapshot copied an immutable sealed chunk")
23 }
24 if got, want := len(history.tail), 1; got != want {
25 t.Fatalf("live tail rows = %d, want %d; snapshot sealed it", got, want)
26 }
27 history.tail[0][0].Rune = 'X'
28 if got, want := rowText(view.Tail().Row(0)), "CCCC"; got != want {
29 t.Fatalf("snapshot tail = %q, want %q", got, want)
30 }
31 if got, want := view.Len(), 3; got != want {
32 t.Fatalf("snapshot rows = %d, want %d", got, want)
33 }
34 if got, want := view.Cells(), 12; got != want {
35 t.Fatalf("snapshot cells = %d, want %d", got, want)
36 }
37
38 tail, err := MarshalHistoryTail(view)
39 require.NoError(t, err)
40 decoded, err := UnmarshalHistory(tail)
41 require.NoError(t, err)
42 require.Equal(t, []string{"CCCC"}, historyViewTexts(decoded))
43}
44
45func TestHistoryFromBlobsNormalizesFullTailBeforeAppend(t *testing.T) {
46 fullTail, err := MarshalHistory(HistoryView{
47 chunks: []*HistoryChunk{{rows: [][]renderer.Cell{historyRow("AAAA"), historyRow("BBBB")}}},
48 rows: 2,
49 })
50 require.NoError(t, err)
51
52 restored, err := HistoryFromBlobs(HistoryConfig{MaxRows: 4, ChunkRows: 2}, nil, fullTail)
53 require.NoError(t, err)
54 requireHistoryAppend(t, restored, historyRow("CCCC"))
55
56 require.Equal(t, []string{"AAAA", "BBBB", "CCCC"}, historyViewTexts(restored.View()))
57 require.Len(t, restored.chunks, 1, "a full restored tail must become sealed")
58 require.Len(t, restored.tail, 1, "the appended row must be the mutable tail")
59}
60
61func TestHistoryFromBlobsRestoresCellAccountingAndEvictsToBothBudgets(t *testing.T) {
62 history := NewHistory(HistoryConfig{MaxRows: 4, MaxCells: 10, ChunkRows: 2})
63 for _, text := range []string{"a", "b", "cc"} {
64 requireHistoryAppend(t, history, historyRow(text))
65 }
66 view := history.SnapshotView()
67 sealed := make([][]byte, view.ChunkCount())
68 for i := range sealed {
69 var err error
70 sealed[i], err = MarshalHistoryChunk(view.Chunk(i))
71 require.NoError(t, err)
72 }
73 tail, err := MarshalHistoryTail(view)
74 require.NoError(t, err)
75
76 restored, err := HistoryFromBlobs(HistoryConfig{MaxRows: 4, MaxCells: 2, ChunkRows: 2}, sealed, tail)
77 require.NoError(t, err)
78 require.Equal(t, []string{"cc"}, historyViewTexts(restored.View()))
79 require.Equal(t, 2, restored.Cells())
80}