File: scrollPosition_test.go

package info (click to toggle)
moor 2.10.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,960 kB
  • sloc: sh: 229; ansic: 12; xml: 6; makefile: 5
file content (138 lines) | stat: -rw-r--r-- 4,701 bytes parent folder | download
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:        &currentStartLine,
			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)
	}
}