Cell canvas renderer with frame cache and a perceptual 256-colour quantizer; responsive geometry (large/medium/small/too-small); squarified treemap with nested previews, LOD grouping, category colouring and adaptive labels; spatial arrow navigation with stable NodeID selection; zoom and breadcrumbs; modal system (info, help, confirm, save); list, file-type, top-N, scan-info, duplicate and comparison views; live search/filter; mouse support; move-to-trash.
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
package tui
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/andydixon/mapsize/internal/inventory"
|
|
"github.com/andydixon/mapsize/internal/scan"
|
|
)
|
|
|
|
// TestLiveScanRendering renders, navigates, filters and resizes while the
|
|
// scanner mutates the inventory. Run with -race to verify the locking
|
|
// discipline.
|
|
func TestLiveScanRendering(t *testing.T) {
|
|
root := t.TempDir()
|
|
for i := range 30 {
|
|
d := filepath.Join(root, fmt.Sprintf("d%02d", i), "sub")
|
|
if err := os.MkdirAll(d, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for j := range 40 {
|
|
os.WriteFile(filepath.Join(d, fmt.Sprintf("f%d.log", j)), make([]byte, (i+1)*(j+1)*100), 0o644)
|
|
}
|
|
}
|
|
start := func(ctx context.Context) (*scan.Scanner, *inventory.Tree, error) {
|
|
s, err := scan.Start(ctx, root, scan.Options{Workers: 4, ChunkSize: 3})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return s, s.Tree, nil
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
s, tr, err := start(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m := newModel(Options{Start: start}, s, tr, cancel)
|
|
sizes := [][2]int{{120, 40}, {80, 24}, {200, 60}, {45, 12}}
|
|
deadline := time.After(20 * time.Second)
|
|
for i := 0; ; i++ {
|
|
send(m, size(sizes[i%len(sizes)][0], sizes[i%len(sizes)][1]), tickMsg(time.Now()))
|
|
send(m, key([]string{"right", "down", "left", "up"}[i%4]))
|
|
if i%5 == 0 {
|
|
send(m, key("tab"))
|
|
}
|
|
if i == 3 {
|
|
m.search.ed.set("ext = log")
|
|
m.queryChanged()
|
|
send(m, m.applyFilter()())
|
|
}
|
|
m.dirty = true
|
|
m.View()
|
|
select {
|
|
case <-s.Done():
|
|
send(m, scanDoneMsg{s})
|
|
m.View()
|
|
if m.scanning {
|
|
t.Fatal("scan should be finished")
|
|
}
|
|
return
|
|
case <-deadline:
|
|
t.Fatal("scan did not finish")
|
|
default:
|
|
}
|
|
}
|
|
}
|