cat / 012
clone

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

cat/module-path
012 / internal / ui / names_test.go
names_test.go 4.1K
1package ui23import (4 "strings"5 "testing"67 "src.rest/cat/012/internal/sheet"8)910func rectOf(s string) sheet.Rect {11 r, _ := sheet.ParseRange(s)12 return r13}1415func TestDefineNameFromSelection(t *testing.T) {16 m := newModel()17 press(t, m, "<right>", "10", "<enter>", "20", "<enter>", "<up>", "<shift+up>")18 m.runCommand("data.define_name")19 if l := line(m, contextLine); !strings.HasPrefix(l, "Name for B1:B2:") {20 t.Fatalf("prompt %q", l)21 }22 press(t, m, "Sales", "<enter>")23 if n, ok := m.sheet.LookupName("sales"); !ok || n.Range != rectOf("B1:B2") {24 t.Fatalf("name %v %v", n, ok)25 }26 if l := line(m, contextLine); !strings.Contains(l, "=SUM(Sales)") {27 t.Errorf("note %q", l)28 }29 // The name box shows the name of the selected range.30 if l := line(m, formulaLine); !strings.HasPrefix(l, " Sales") {31 t.Errorf("name box %q", l)32 }33 press(t, m, "<esc>", "<down>", "<down>", "=SUM(Sales)", "<enter>")34 if m.sheet.Value(addr("B3")).Num != 30 {35 t.Errorf("B3 = %v", m.sheet.Value(addr("B3")))36 }37 press(t, m, "<ctrl+z>", "<ctrl+z>")38 if _, ok := m.sheet.LookupName("Sales"); ok {39 t.Error("undo kept the name")40 }4142 // A bad name says why.43 m.runCommand("data.define_name")44 press(t, m, "A1", "<enter>")45 if m.mode != modeError || !strings.Contains(m.errMsg, "cell reference") {46 t.Errorf("mode %v %q", m.mode, m.errMsg)47 }48}4950func TestNamedRangesPicker(t *testing.T) {51 m := tallModel()52 m.Update(teaSize(120, 40))53 m.sheet.Set(addr("A1"), "=SUM(Costs)+Rate")54 m.sheet.DefineName("Costs", rectOf("C2:C9"))55 m.sheet.DefineName("Rate", rectOf("E1"))56 press(t, m, "<alt+d>")57 if !strings.Contains(screen(m), "Named ranges") || !strings.Contains(screen(m), "Formula tracing") {58 t.Fatalf("Data menu:\n%s", screen(m))59 }60 press(t, m, "<esc>")61 m.runCommand("data.named_ranges")62 scr := screen(m)63 for _, want := range []string{"+ Add a range", "Costs", "C2:C9", "Rate", "E1"} {64 if !strings.Contains(scr, want) {65 t.Errorf("missing %q in\n%s", want, scr)66 }67 }68 press(t, m, "cos")69 if st := line(m, m.height-1); !strings.Contains(st, "used in 1 formula") || !strings.Contains(st, "F2 edit") {70 t.Errorf("status %q", st)71 }72 press(t, m, "<enter>")73 if m.mode != modeReady || m.selection() != rectOf("C2:C9") {74 t.Fatalf("go to: %v %v", m.mode, m.selection())75 }7677 // F2 renames and repoints; formulas follow the new name.78 m.runCommand("data.named_ranges")79 press(t, m, "rate", "<f2>")80 if l := line(m, contextLine); !strings.HasPrefix(l, "Rename Rate: Rate") {81 t.Fatalf("rename prompt %q", l)82 }83 press(t, m, "Tax", "<enter>")84 if l := line(m, contextLine); !strings.HasPrefix(l, "Range for Tax: E1") {85 t.Fatalf("range prompt %q", l)86 }87 press(t, m, "<shift+down>", "<enter>")88 if n, _ := m.sheet.LookupName("tax"); n.Range != rectOf("E1:E2") || input(m, "A1") != "=SUM(Costs)+Tax" {89 t.Fatalf("edited: %v %q", n, input(m, "A1"))90 }91 if _, ok := m.overlay.(*namesPicker); !ok {92 t.Fatal("picker didn't come back")93 }9495 // Ctrl+D deletes; the picker stays open and says how to undo.96 press(t, m, "tax", "<ctrl+d>")97 if _, ok := m.sheet.LookupName("Tax"); ok {98 t.Fatal("not deleted")99 }100 if st := line(m, m.height-1); !strings.Contains(st, "Deleted Tax") {101 t.Errorf("status %q", st)102 }103 press(t, m, "<esc>", "<ctrl+z>")104 if _, ok := m.sheet.LookupName("Tax"); !ok {105 t.Error("undo didn't restore")106 }107108 // Add a range names the selection the picker opened with.109 press(t, m, "<ctrl+home>", "<shift+right>")110 m.runCommand("data.named_ranges")111 press(t, m, "<enter>", "Top", "<enter>")112 if n, ok := m.sheet.LookupName("Top"); !ok || n.Range != rectOf("A1:B1") {113 t.Errorf("added %v %v", n, ok)114 }115}116117func TestGotoAcceptsNamesAndRanges(t *testing.T) {118 m := newModel()119 m.sheet.DefineName("Totals", rectOf("D4:E6"))120 press(t, m, "<f5>", "totals", "<enter>")121 if m.selection() != rectOf("D4:E6") {122 t.Errorf("name: %v", m.selection())123 }124 press(t, m, "<f5>", "B2:C3", "<enter>")125 if m.selection() != rectOf("B2:C3") {126 t.Errorf("range: %v", m.selection())127 }128 press(t, m, "<f5>", "nope", "<enter>")129 if m.mode != modeError || m.errMsg != "Not a cell, range, named range, table or region: nope" {130 t.Errorf("%v %q", m.mode, m.errMsg)131 }132}