cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / ui / assistsheets_test.go
assistsheets_test.go 3.5K
1package ui23import (4 "strings"5 "testing"67 "src.rest/cat/012/internal/ui/suggest"8)910// sheetsModel has Sheet1 (shown), Summary with 7 in B3, and Q3 plan with11// 5 in A2.12func sheetsModel(t *testing.T) *Model {13 t.Helper()14 m := newModel()15 book := m.book()16 sum, _ := book.AddSheet("Summary", 1)17 sum.Set(addr("B3"), "7")18 plan, _ := book.AddSheet("Q3 plan", 2)19 plan.Set(addr("A2"), "5")20 book.ClearHistory()21 return m22}2324func names(list []suggest.Suggestion) []string {25 var out []string26 for _, s := range list {27 out = append(out, s.Name)28 }29 return out30}3132func TestAutocompleteSheets(t *testing.T) {33 m := sheetsModel(t)34 press(t, m, "=su")35 list, _ := m.entry.assist.Shown(m.host())36 got := names(list)37 if len(got) < 2 || got[0] != "Summary!" || !strings.HasPrefix(got[1], "SU") {38 t.Fatalf("suggestions %v", got)39 }40 if scr := screen(m); !strings.Contains(scr, "│ Summary! sheet, A1:B3") {41 t.Errorf("list:\n%s", scr)42 }43 if st := status(m); !strings.Contains(st, "Sheet Summary: A1:B3, 1 cell") {44 t.Errorf("status %q", st)45 }46 press(t, m, "<tab>")47 if m.line.Text() != "=Summary!" || m.mode != modeEnter {48 t.Fatalf("accepted: %q, mode %v", m.line.Text(), m.mode)49 }50 // Typing the address works as ever.51 press(t, m, "B3*2", "<enter>")52 if m.sheet.Value(addr("A1")).Num != 14 {53 t.Errorf("A1 = %v (%q)", m.sheet.Value(addr("A1")), input(m, "A1"))54 }5556 // A name that needs quotes is offered quoted, from its start or57 // inside quotes.58 for _, typed := range []string{"=q3", "='q3 p", "='pl"} {59 press(t, m, "<esc>", "<esc>", typed)60 list, start := m.entry.assist.Shown(m.host())61 if len(list) == 0 || list[0].Name != "'Q3 plan'!" || start != 1 {62 t.Errorf("%s: %v from %d", typed, names(list), start)63 }64 }65 press(t, m, "<tab>")66 if m.line.Text() != "='Q3 plan'!" {67 t.Fatalf("quoted: %q", m.line.Text())68 }69 // An arrow then points into the sheet, as clicking its tab would.70 press(t, m, "<down>")71 if m.mode != modePoint || m.sheet.Name() != "Q3 plan" || m.pointRef() != "'Q3 plan'!A2" {72 t.Fatalf("pointing: mode %v on %s, %q", m.mode, m.sheet.Name(), m.pointRef())73 }74 press(t, m, "+1", "<enter>")75 if m.sheet.Name() != "Sheet1" || input(m, "A2") != "='Q3 plan'!A2+1" || m.sheet.Value(addr("A2")).Num != 6 {76 t.Errorf("stored on %s: %q", m.sheet.Name(), input(m, "A2"))77 }78}7980// The entry's own sheet isn't offered, and pointing after its name typed81// keeps the name; hidden sheets aren't offered, and a quote closing the82// name isn't doubled.83func TestAutocompleteSheetsEdges(t *testing.T) {84 m := sheetsModel(t)85 press(t, m, "=she")86 if list, _ := m.entry.assist.Shown(m.host()); len(list) > 0 && list[0].Name == "Sheet1!" {87 t.Errorf("the formula's own sheet offered: %v", names(list))88 }89 press(t, m, "et1!", "<right>")90 if m.mode != modePoint || m.sheet.Name() != "Sheet1" || m.pointRef() != "B1" {91 t.Fatalf("own sheet pointing: %v %s %q", m.mode, m.sheet.Name(), m.pointRef())92 }93 press(t, m, "<esc>", "<esc>")9495 m.book().HideSheet(m.book().Lookup("Summary"))96 press(t, m, "=summ")97 if list, _ := m.entry.assist.Shown(m.host()); len(list) > 0 && list[0].Name == "Summary!" {98 t.Errorf("hidden sheet offered: %v", names(list))99 }100 press(t, m, "<esc>")101102 // Accepting inside an existing reference replaces the name only.103 m.line.Set("='Q3 p'!A1")104 m.line.Pos = len("='Q3 p")105 m.entry.assist.Active = true106 m.mode = modeEnter107 press(t, m, "<tab>")108 if m.line.Text() != "='Q3 plan'!A1" || m.line.Pos != len("='Q3 plan'!") {109 t.Errorf("replaced: %q at %d", m.line.Text(), m.line.Pos)110 }111}