8 "github.com/stretchr/testify/require"
11 func TestViewMergesInTheOrderOfTaelinsPush(t *testing.T) {
15 for tick := range 20001 {
16 states = push(tick, states)
17 starts := states.starts()
18 view.high = len(starts)
19 view.low = len(starts)
22 lines := make([]int, len(view.lines))
23 for n, line := range view.lines {
24 lines[n] = line.index << line.level
27 require.Equal(t, starts, lines, "t=%d", tick)
31 func TestViewMergesInOneBatchFromHighToLow(t *testing.T) {
33 view := newView(10, 5)
34 sizes := make([]int, 0, 20)
37 sizes = append(sizes, view.Size(tree))
40 require.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 6, 7, 8, 9, 10, 5, 6, 7, 8}, sizes)
43 func TestViewMergesOnlyBuiltParents(t *testing.T) {
45 sizes: map[nodeKey]int{
60 require.Equal(t, []nodeKey{{0, 0}, {0, 1}, {0, 2}, {0, 3}}, view.lines)
61 require.True(t, view.merging)
63 tree.sizes[nodeKey{1, 0}] = 1
65 require.Equal(t, []nodeKey{{1, 0}, {0, 2}, {0, 3}, {0, 4}}, view.lines)
66 require.True(t, view.merging)
68 tree.sizes[nodeKey{1, 1}] = 1
69 tree.sizes[nodeKey{1, 2}] = 1
70 tree.sizes[nodeKey{2, 0}] = 1
72 require.Equal(t, []nodeKey{{2, 0}, {1, 2}}, view.lines)
73 require.False(t, view.merging)
76 func TestViewRendersPendingLinesWithoutTheirMessage(t *testing.T) {
78 sizes: map[nodeKey]int{
85 view, err := restoreView(viewState{
86 Lines: [][2]int{{1, 0}, {0, 2}},
87 }, chatHigh, chatLow, tree)
88 require.NoError(t, err)
89 require.Equal(t, "<chat>\n0+2|aaa aaa\n2+1|"+pending+"\n</chat>", view.Render(tree))
90 require.Equal(t, 7+len(pending), view.Size(tree))
93 func TestViewCoarsenTakesTheCoarserLines(t *testing.T) {
94 view, err := restoreView(viewState{
95 Lines: [][2]int{{1, 0}, {0, 2}, {0, 3}, {0, 4}, {0, 5}},
96 }, 100, 100, builtTree{})
97 require.NoError(t, err)
99 other, err := restoreView(viewState{
100 Lines: [][2]int{{0, 0}, {0, 1}, {1, 1}, {0, 4}, {0, 5}},
101 }, 100, 100, builtTree{})
102 require.NoError(t, err)
104 view.Coarsen(other, builtTree{})
105 require.Equal(t, []nodeKey{{1, 0}, {1, 1}, {0, 4}, {0, 5}}, view.lines)
108 view.Coarsen(other, builtTree{})
109 require.Equal(t, []nodeKey{{2, 0}, {1, 2}}, view.lines)
110 require.False(t, view.merging)
113 func TestViewContextStopsAtTheFirstPendingLine(t *testing.T) {
115 sizes: map[nodeKey]int{
123 view, err := restoreView(viewState{
124 Lines: [][2]int{{1, 0}, {0, 2}, {0, 3}},
126 require.NoError(t, err)
127 require.Equal(t, "<chat>\n</chat>", view.Context(tree, 0))
128 require.Equal(t, "<chat>\n0+2|a\n</chat>", view.Context(tree, 2))
129 require.Equal(t, "<chat>\n0+2|a\n</chat>", view.Context(tree, 3))
132 func TestRestoreViewRejectsAGap(t *testing.T) {
133 _, err := restoreView(viewState{
134 Lines: [][2]int{{0, 0}, {0, 2}},
135 }, chatHigh, chatLow, builtTree{})
136 require.ErrorContains(t, err, "does not start at message 1")
139 // pushEntry is one entry of Taelin's rollback state list, newest first. Under
140 // push alone, life stays 0, so the entry leaves it out.
141 type pushEntry struct {
147 // push is the push of rollback_state_list.js.
148 func push(state int, states *pushEntry) *pushEntry {
165 older: push(states.state, states.older),
169 // starts returns the states of the list, oldest first.
170 func (e *pushEntry) starts() []int {
172 for entry := e; entry != nil; entry = entry.older {
173 starts = append(starts, entry.state)
176 slices.Reverse(starts)
181 // builtTree is a tree with each node built, with 1 byte of text.
182 type builtTree struct{}
184 func (builtTree) Node(level, index int) (Node, bool) {
185 return testNode(level, index, "a"), true
188 // partTree is a tree with the built nodes of its sizes.
189 type partTree struct {
190 sizes map[nodeKey]int
193 func (p partTree) Node(level, index int) (Node, bool) {
194 size, built := p.sizes[nodeKey{level, index}]
199 text := strings.Repeat("a", size)
204 return testNode(level, index, text), true