1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
package internal
import (
"fmt"
"strings"
"testing"
"github.com/walles/moor/v2/internal/linemetadata"
"github.com/walles/moor/v2/internal/reader"
"github.com/walles/moor/v2/twin"
"gotest.tools/v3/assert"
)
const screenHeight = 60
// Repro for: https://github.com/walles/moor/issues/166
func testCanonicalize1000(t *testing.T, withStatusBar bool, currentStartLine linemetadata.Index, lastVisibleLine linemetadata.Index) {
pager := Pager{}
pager.screen = twin.NewFakeScreen(100, screenHeight)
pager.readers = []*reader.ReaderImpl{reader.NewFromTextForTesting("test", strings.Repeat("a\n", 2000))}
pager.filteringReader = FilteringReader{
BackingReader: pager.readers[pager.currentReader],
Filter: &pager.filter,
}
pager.ShowLineNumbers = true
pager.showLineNumbers = true
pager.ShowStatusBar = withStatusBar
pager.scrollPosition = scrollPosition{
internalDontTouch: scrollPositionInternal{
lineIndex: ¤tStartLine,
deltaScreenLines: 0,
name: "findFirstHit",
canonicalizing: false,
},
}
lastVisiblePosition := scrollPosition{
internalDontTouch: scrollPositionInternal{
lineIndex: &lastVisibleLine,
deltaScreenLines: 0,
name: "Last Visible Position",
},
}
assert.Equal(t, *lastVisiblePosition.lineIndex(&pager), lastVisibleLine)
}
func TestCanonicalize1000WithStatusBar(t *testing.T) {
for startLine := 0; startLine < 1500; startLine++ {
t.Run(fmt.Sprint("startLine=", startLine), func(t *testing.T) {
testCanonicalize1000(t, true,
linemetadata.IndexFromZeroBased(startLine),
linemetadata.IndexFromZeroBased(startLine+screenHeight-2),
)
})
}
}
func TestCanonicalize1000WithoutStatusBar(t *testing.T) {
for startLine := 0; startLine < 1500; startLine++ {
t.Run(fmt.Sprint("startLine=", startLine), func(t *testing.T) {
testCanonicalize1000(t, true,
linemetadata.IndexFromZeroBased(startLine),
linemetadata.IndexFromZeroBased(startLine+screenHeight-1),
)
})
}
}
// Try scrolling between two points, on a 80 x screenHeight screen with 1492
// lines of input.
func tryScrollAmount(t *testing.T, scrollFrom linemetadata.Index, scrollDistance int) {
// Create 1492 lines of single-char content
pager := Pager{}
pager.screen = twin.NewFakeScreen(80, screenHeight)
pager.readers = []*reader.ReaderImpl{reader.NewFromTextForTesting("test", strings.Repeat("x\n", 1492))}
pager.filteringReader = FilteringReader{
BackingReader: pager.readers[pager.currentReader],
Filter: &pager.filter,
}
pager.ShowLineNumbers = true
pager.showLineNumbers = true
pager.scrollPosition = scrollPosition{
internalDontTouch: scrollPositionInternal{
name: "tryScrollAmount",
lineIndex: &scrollFrom,
deltaScreenLines: scrollDistance,
},
}
// Trigger rendering (and canonicalization). If the prefix is miscomputed
// this would previously panic inside createLinePrefix().
rendered := pager.renderLines()
// Sanity check the result
assert.Assert(t, rendered.lines != nil)
assert.Equal(t, len(rendered.lines), pager.visibleHeight())
assert.Equal(t, rendered.lines[0].inputLineIndex, scrollFrom.NonWrappingAdd(scrollDistance))
}
// Repro for https://github.com/walles/moor/issues/313: Rapid scroll
// (deltaScreenLines > 0) crossing from 3 to 4 digits must not panic due to
// too-short number prefix length.
func TestFastScrollAcross1000DoesNotPanic(t *testing.T) {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(900), 200)
}
// Repro for https://github.com/walles/moor/issues/338
func TestIssue338(t *testing.T) {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(1000), -60)
}
func TestMultipleScrollStartsAcross1000DoNotPanic(t *testing.T) {
for scrollFrom := 1000 - screenHeight - 10; scrollFrom <= 1000; scrollFrom++ {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(scrollFrom), screenHeight)
}
}
func TestMultipleScrollDistancesAcross1000DoNotPanic(t *testing.T) {
scrollFrom := 1000 - screenHeight - 10
for scrollDistance := 0; scrollDistance <= 3*screenHeight; scrollDistance++ {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(scrollFrom), scrollDistance)
}
}
func TestMultipleBackwardsScrollStartsAcross1000DoNotPanic(t *testing.T) {
for scrollFrom := 1000 + screenHeight + 10; scrollFrom >= 1000; scrollFrom-- {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(scrollFrom), -screenHeight)
}
}
func TestMultipleBackwardsScrollDistancesAcross1000DoNotPanic(t *testing.T) {
scrollFrom := 1000 + screenHeight + 10
for scrollDistance := 0; scrollDistance <= 3*screenHeight; scrollDistance++ {
tryScrollAmount(t, linemetadata.IndexFromZeroBased(scrollFrom), -scrollDistance)
}
}
|