cat / 012
clone

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

main
012 / internal / sheet / trace_test.go
trace_test.go 3.3K
1package sheet23import (4 "strings"5 "testing"6)78// links writes links as they'd be listed: the range, with its sheet when9// not s, and the kind's name where it isn't a plain reference.10func links(s *Sheet, ls []Link) string {11 var out []string12 for _, l := range ls {13 ref := l.Range.String()14 if l.Sheet != s {15 ref = Qualified(l.Sheet.Name(), l.Range)16 }17 switch l.Kind {18 case LinkName, LinkRegion, LinkFile, LinkOutput:19 ref = l.Name + "=" + ref20 case LinkSpill:21 ref = "spill " + ref22 }23 out = append(out, ref)24 }25 return strings.Join(out, " ")26}2728func TestPrecedentLinks(t *testing.T) {29 s := sheetOf(t, map[string]string{30 "A1": "1", "A2": "2", "B1": "=SEQUENCE(3)", "C1": "=Rate*A1+SUM(B1:B3)", "C2": "=missing!A1+A1",31 })32 s.DefineName("Rate", rect("A2"))33 if got, want := links(s, s.PrecedentLinks(at("C1"))), "Rate=A2 A1 B1:B3"; got != want {34 t.Errorf("C1 = %q, want %q", got, want)35 }36 if got, want := links(s, s.PrecedentLinks(at("C2"))), "A1"; got != want {37 t.Errorf("an unknown sheet: %q, want %q", got, want)38 }39 // A spilled cell comes from its anchor.40 if got, want := links(s, s.PrecedentLinks(at("B3"))), "spill B1"; got != want {41 t.Errorf("B3 = %q, want %q", got, want)42 }43 if got := s.PrecedentLinks(at("A1")); got != nil {44 t.Errorf("a number: %v", got)45 }46}4748func TestDependentLinks(t *testing.T) {49 s := sheetOf(t, map[string]string{50 "A1": "=SEQUENCE(3)", "C1": "=A2*2", "C2": "=SUM(A1:A9)", "C3": "=A1", "D5": "=B1",51 })52 other, _ := s.Book().AddSheet("Other", 1)53 other.Set(at("A1"), "=Sheet1!A3")54 s.DefineName("Mid", rect("A2"))55 other.Set(at("B1"), "=Mid")56 // The anchor's dependents read any cell it spills into.57 got, more := s.DependentLinks(at("A1"), 0)58 if want := "spill A1:A3 C1 C2 C3 Other!A1 Other!B1"; links(s, got) != want || more {59 t.Errorf("A1 = %q (more %v), want %q", links(s, got), more, want)60 }61 if got, _ := s.DependentLinks(at("A2"), 0); links(s, got) != "C1 C2 Other!B1" {62 t.Errorf("A2 = %q", links(s, got))63 }64 // A cap finds that many and says there are more.65 got, more = s.DependentLinks(at("A1"), 2)66 if len(got) != 3 || !more {67 t.Errorf("capped: %q, more %v", links(s, got), more)68 }69 if !s.Reads(at("C2"), s, rect("A3")) || !other.Reads(at("B1"), s, rect("A1:A2")) || s.Reads(at("D5"), s, rect("A1:A3")) {70 t.Error("Reads")71 }72 if s.Reads(at("A2"), s, rect("A1")) {73 t.Error("a spilled cell reads its anchor")74 }75}7677func TestTraceRegions(t *testing.T) {78 s := New()79 nb := sent(t, s, "files", "B2")80 s.Set(at("A1"), "=ROWS(nu.files)")81 apply(t, s, LiveOp{Region: "files", Reset: true, Header: liveRow("n"), Rows: []LiveRow{liveRow("a"), liveRow("b")}})82 if got, want := links(s, s.PrecedentLinks(at("A1"))), "nu.files=B2:B4"; got != want {83 t.Errorf("A1 = %q, want %q", got, want)84 }85 // The region's cells come from the notebook cell.86 if got, want := links(s, s.PrecedentLinks(at("B3"))), "files="+Qualified(nb.Name(), rect("A1")); got != want {87 t.Errorf("B3 = %q, want %q", got, want)88 }89 if got, _ := s.DependentLinks(at("B4"), 0); links(s, got) != "A1" {90 t.Errorf("B4's dependents = %q", links(s, got))91 }92 if !s.Reads(at("A1"), s, rect("B3")) {93 t.Error("Reads through a region")94 }95 if _, err := s.AddLinked(at("F1"), LinkSource{Path: "log.csv"}); err != nil {96 t.Fatal(err)97 }98 if got, want := links(s, s.PrecedentLinks(at("F1"))), "log.csv=F1"; got != want {99 t.Errorf("F1 = %q, want %q", got, want)100 }101}