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 "testing"
4
5func TestIfBranches(t *testing.T) {
6 v := Eval(mustParse(t, `IF(TRUE,"yes","no")`), emptyEnv{})
7 if v.Kind != KindStr || v.Str != "yes" {
8 t.Fatalf("IF(TRUE,...) = %v, want \"yes\"", v)
9 }
10 v = Eval(mustParse(t, `IF(FALSE,"yes","no")`), emptyEnv{})
11 if v.Kind != KindStr || v.Str != "no" {
12 t.Fatalf("IF(FALSE,...) = %v, want \"no\"", v)
13 }
14}
15
16// The untaken branch is still evaluated by evalCall (Func receives
17// finished Values, not thunks), but fnIf only ever returns the
18// already-computed value it selects — so the discarded branch's own
19// error never surfaces in the result.
20func TestIfDiscardsErrorInUntakenBranch(t *testing.T) {
21 v := Eval(mustParse(t, "IF(FALSE,1/0,5)"), emptyEnv{})
22 if v.Kind != KindNum || v.Num != 5 {
23 t.Fatalf("IF(FALSE,1/0,5) = %v, want 5", v)
24 }
25}
26
27func TestIfsFirstTrueWins(t *testing.T) {
28 v := Eval(mustParse(t, "IFS(FALSE,1,TRUE,2,TRUE,3)"), emptyEnv{})
29 if v.Kind != KindNum || v.Num != 2 {
30 t.Fatalf("IFS(...) = %v, want 2", v)
31 }
32}
33
34func TestIfsNoTrueIsNA(t *testing.T) {
35 v := Eval(mustParse(t, "IFS(FALSE,1,FALSE,2)"), emptyEnv{})
36 if v.Kind != KindErr || v.Err != ErrNA {
37 t.Fatalf("IFS(all false) = %v, want #N/A", v)
38 }
39}
40
41func TestAndOrNot(t *testing.T) {
42 v := Eval(mustParse(t, "AND(TRUE,TRUE,TRUE)"), emptyEnv{})
43 if v.Kind != KindBool || !v.Bool {
44 t.Fatalf("AND(T,T,T) = %v, want TRUE", v)
45 }
46 v = Eval(mustParse(t, "AND(TRUE,FALSE)"), emptyEnv{})
47 if v.Kind != KindBool || v.Bool {
48 t.Fatalf("AND(T,F) = %v, want FALSE", v)
49 }
50 v = Eval(mustParse(t, "OR(FALSE,FALSE,TRUE)"), emptyEnv{})
51 if v.Kind != KindBool || !v.Bool {
52 t.Fatalf("OR(F,F,T) = %v, want TRUE", v)
53 }
54 v = Eval(mustParse(t, "NOT(TRUE)"), emptyEnv{})
55 if v.Kind != KindBool || v.Bool {
56 t.Fatalf("NOT(TRUE) = %v, want FALSE", v)
57 }
58}
59
60func TestAndPropagatesError(t *testing.T) {
61 env := mapEnv{{1, 1}: {Kind: KindErr, Err: ErrRef}}
62 v := Eval(mustParse(t, "AND(A1,TRUE)"), env)
63 if v.Kind != KindErr || v.Err != ErrRef {
64 t.Fatalf("AND(A1,TRUE) = %v, want #REF!", v)
65 }
66}
67
68// IFERROR is the one place a formula is allowed to inspect an error
69// argument instead of becoming it (evalCall does not short-circuit on an
70// error argument for exactly this reason).
71func TestIfError(t *testing.T) {
72 v := Eval(mustParse(t, `IFERROR(1/0,"fallback")`), emptyEnv{})
73 if v.Kind != KindStr || v.Str != "fallback" {
74 t.Fatalf(`IFERROR(1/0,"fallback") = %v, want "fallback"`, v)
75 }
76 v = Eval(mustParse(t, `IFERROR(5,"fallback")`), emptyEnv{})
77 if v.Kind != KindNum || v.Num != 5 {
78 t.Fatalf(`IFERROR(5,"fallback") = %v, want 5`, v)
79 }
80}
81