oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1package calc
2
3import (
4 "testing"
5 "time"
6)
7
8// The graph tests key cells by hand rather than through a real binder
9// (task 10 owns binding). RowID/ColID here are exactly refKey's position-
10// plus-one convention, so a formula's "A1" and the test's cellA1 name the
11// same CellKey.
12var (
13 cellA1 = CellKey{RowID: 1, ColID: 1}
14 cellB1 = CellKey{RowID: 1, ColID: 2}
15 cellC1 = CellKey{RowID: 1, ColID: 3}
16 cellZ9 = CellKey{RowID: 9, ColID: 26}
17)
18
19// env gives A1 a raw input value so B1 (=A1*2) and C1 (=B1+1) have
20// something concrete to compute from; it is shared read-only by every
21// test in this file, none of which mutate it.
22var env = mapEnv{cellA1: {Kind: KindNum, Num: 10}}
23
24func TestDirtySetTouchesOnlyDependents(t *testing.T) {
25 g := NewGraph()
26 g.SetFormula(cellB1, mustParse(t, "A1*2"))
27 g.SetFormula(cellC1, mustParse(t, "B1+1"))
28 g.SetFormula(cellZ9, mustParse(t, "42")) // unrelated
29
30 touched := g.Recalc(cellA1, env)
31 if touched != 2 {
32 t.Fatalf("touched %d cells, want 2 (B1, C1) — Z9 must not recalc", touched)
33 }
34}
35
36// A cycle must return an error value, not hang. This test has a timeout
37// because the failure mode of getting this wrong is a wedged process.
38func TestCycleDetection(t *testing.T) {
39 g := NewGraph()
40 g.SetFormula(cellA1, mustParse(t, "B1"))
41 g.SetFormula(cellB1, mustParse(t, "A1"))
42 done := make(chan Value, 1)
43 go func() { done <- g.Value(cellA1, env) }()
44 select {
45 case v := <-done:
46 if v.Kind != KindErr || v.Err != ErrCircular {
47 t.Fatalf("cycle = %v, want #CIRCULAR!", v)
48 }
49 case <-time.After(2 * time.Second):
50 t.Fatal("cycle detection hung")
51 }
52}
53