Pad/internal/browser/pixel_scroll_test.go
Greg Pomerantz 06b1444207 gofmt: format all remaining files with the go1.27 toolchain
The tree was formatted with an older gofmt; go1.27's gofmt additionally
wants: EOF exactly one newline (no trailing blank lines), imports sorted
alphabetically within a block, mixed-precedence binary expressions
re-spaced for grouping ((a+b)/c), single-field composite literals
un-aligned, adjacent one-line method signatures aligned, and one-line
bodies containing a compound statement expanded. Applied repo-wide
(31 files under internal/); pure formatting, no semantic changes —
build and the full test suite pass.
2026-08-23 10:03:27 -04:00

265 lines
7.0 KiB
Go

package browser
import (
"testing"
)
// --- Test: Per-Pixel Scroll Delta Applied Correctly ---
func TestPixelScroll_DeltaApplied(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0 // pixels per entry
s.ScrollOffset = 0
// Scroll down by 100 pixels (should be precise, not rounded to entries)
HandlePixelScroll(s, 100)
// ScrollOffset should be 100.0 (exact pixel delta)
expected := 100.0
if s.ScrollOffset != expected {
t.Errorf("expected ScrollOffset=%.1f, got %.1f", expected, s.ScrollOffset)
}
// Scroll up by 50 pixels
HandlePixelScroll(s, -50)
expected = 50.0
if s.ScrollOffset != expected {
t.Errorf("expected ScrollOffset=%.1f, got %.1f", expected, s.ScrollOffset)
}
}
// --- Test: Per-Pixel Scroll Clamped to Minimum ---
func TestPixelScroll_ClampMinimum(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Try to scroll above the top
HandlePixelScroll(s, -100)
// ScrollOffset should be clamped to 0
if s.ScrollOffset != 0 {
t.Errorf("expected ScrollOffset=0 (clamped), got %.1f", s.ScrollOffset)
}
}
// --- Test: Per-Pixel Scroll Clamped to Maximum ---
func TestPixelScroll_ClampMaximum(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Maximum scroll = (TotalEntries - VisibleCount) * EntryHeight
maxScroll := float64(s.TotalEntries-s.VisibleCount) * s.EntryHeight
// Try to scroll past the bottom
HandlePixelScroll(s, int(maxScroll)+1000)
// ScrollOffset should be clamped to max
if s.ScrollOffset != maxScroll {
t.Errorf("expected ScrollOffset=%.1f (clamped to max), got %.1f", maxScroll, s.ScrollOffset)
}
}
// --- Test: Per-Pixel Scroll Preserves Sub-Entry Precision ---
func TestPixelScroll_SubEntryPrecision(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Scroll by a value that doesn't align to entry boundaries
// 73 pixels = 1 full entry (48px) + 25 pixels into the next entry
HandlePixelScroll(s, 73)
expected := 73.0
if s.ScrollOffset != expected {
t.Errorf("expected ScrollOffset=%.1f (sub-entry precision), got %.1f", expected, s.ScrollOffset)
}
// Scroll another 100 pixels (total 173 = 3 entries + 29px)
HandlePixelScroll(s, 100)
expected = 173.0
if s.ScrollOffset != expected {
t.Errorf("expected ScrollOffset=%.1f (accumulated sub-entry precision), got %.1f", expected, s.ScrollOffset)
}
}
// --- Test: Pixel Scroll Index Derived from Offset ---
func TestPixelScroll_IndexFromOffset(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Initial index should be 0
if s.GetScrollIndex() != 0 {
t.Errorf("expected initial ScrollIndex=0, got %d", s.GetScrollIndex())
}
// Scroll down by 100 pixels
HandlePixelScroll(s, 100)
// ScrollIndex should be floor(100 / 48) = 2
expectedIndex := 2
if s.GetScrollIndex() != expectedIndex {
t.Errorf("expected ScrollIndex=%d (from offset 100 / height 48), got %d", expectedIndex, s.GetScrollIndex())
}
// Scroll up by 50 pixels (offset now 50)
HandlePixelScroll(s, -50)
// ScrollIndex should be floor(50 / 48) = 1
expectedIndex = 1
if s.GetScrollIndex() != expectedIndex {
t.Errorf("expected ScrollIndex=%d (from offset 50 / height 48), got %d", expectedIndex, s.GetScrollIndex())
}
}
// --- Test: Pixel Scroll Eviction Triggered ---
func TestPixelScroll_EvictionTriggered(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 5000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Load pages at various positions
entries := make([]Entry, 5000)
for i := 0; i < 5000; i++ {
entries[i] = NewEntry("/test/file.txt", "file.txt", 100, s.TapTimestamp, false)
}
s.SortIndex = &DirectoryIndex{
Entries: entries,
SortOrders: map[string][]int{
"name_asc": buildPositionMap(entries, SortModeNameAsc),
"date_desc": buildPositionMap(entries, SortModeDateDesc),
},
}
for pageIdx := 0; pageIdx <= 10; pageIdx++ {
p := loadPageFromIndex(s, pageIdx)
if p != nil {
s.Pages[pageIdx] = p
}
}
// Scroll far away using pixel offset
// Scroll to page 40+ (40 * 100 * 48 = 192000 pixels)
HandlePixelScroll(s, 192000)
// Pages far from current position should be evicted
// Check that page 0 was evicted (it's far from page 40)
if page, exists := s.Pages[0]; exists && page.Loaded {
t.Error("expected page 0 to be evicted after scrolling far away")
}
}
// --- Test: Pixel Scroll Prefetch Triggered ---
func TestPixelScroll_PrefetchTriggered(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 2000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Load some pages around current position
entries := make([]Entry, 2000)
for i := 0; i < 2000; i++ {
entries[i] = NewEntry("/test/file.txt", "file.txt", 100, s.TapTimestamp, false)
}
s.SortIndex = &DirectoryIndex{
Entries: entries,
SortOrders: map[string][]int{
"name_asc": buildPositionMap(entries, SortModeNameAsc),
"date_desc": buildPositionMap(entries, SortModeDateDesc),
},
}
for pageIdx := 3; pageIdx <= 7; pageIdx++ {
p := loadPageFromIndex(s, pageIdx)
if p != nil {
s.Pages[pageIdx] = p
}
}
// Record current page count
pagesBefore := len(s.Pages)
// Scroll to trigger prefetch using pixel offset
HandlePixelScroll(s, 200*48) // Scroll to page ~7
// After scroll, prefetch should have been triggered
// Page count may have increased due to prefetch
if len(s.Pages) < pagesBefore {
t.Errorf("expected page count to not decrease after scroll, before=%d, after=%d", pagesBefore, len(s.Pages))
}
}
// --- Test: Pixel Scroll With Small Directory ---
func TestPixelScroll_SmallDirectory(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 10 // Smaller than VisibleCount
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Try to scroll down (should be clamped since no scrollable area)
HandlePixelScroll(s, 1000)
// ScrollOffset should be 0 (can't scroll beyond available entries)
if s.ScrollOffset != 0 {
t.Errorf("expected ScrollOffset=0 for small directory, got %.1f", s.ScrollOffset)
}
}
// --- Test: Pixel Scroll To Beginning ---
func TestPixelScroll_ToBeginning(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 500 * 48 // Somewhere in the middle
// Scroll all the way to the beginning
HandlePixelScroll(s, -100000)
if s.ScrollOffset != 0 {
t.Errorf("expected ScrollOffset=0 at beginning, got %.1f", s.ScrollOffset)
}
}
// --- Test: Pixel Scroll To End ---
func TestPixelScroll_ToEnd(t *testing.T) {
s := NewBrowserState()
s.TotalEntries = 1000
s.VisibleCount = 20
s.EntryHeight = 48.0
s.ScrollOffset = 0
// Scroll all the way to the end
maxScroll := float64(s.TotalEntries-s.VisibleCount) * s.EntryHeight
HandlePixelScroll(s, int(maxScroll)+1000)
if s.ScrollOffset != maxScroll {
t.Errorf("expected ScrollOffset=%.1f at end, got %.1f", maxScroll, s.ScrollOffset)
}
}