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// pinnedEnv answers every cell as blank and Now() as a fixed instant —
9// the minimal Env a NOW()/TODAY() unit test needs, independent of
10// corpus_test.go's clockEnv (which additionally models advancing a wall
11// clock that Now() ignores).
12type pinnedEnv time.Time
13
14func (p pinnedEnv) CellValue(CellKey) Value { return Value{} }
15func (p pinnedEnv) Now() time.Time { return time.Time(p) }
16
17func TestNowUsesEnvClock(t *testing.T) {
18 env := pinnedEnv(time.Date(2026, 8, 30, 12, 0, 0, 0, time.UTC))
19 v := Eval(mustParse(t, "NOW()"), env)
20 if v.Kind != KindNum {
21 t.Fatalf("NOW() Kind = %v, want KindNum", v.Kind)
22 }
23 want := dateSerial(time.Time(env))
24 if v.Num != want {
25 t.Fatalf("NOW() = %v, want %v", v.Num, want)
26 }
27}
28
29// TODAY truncates the time of day to midnight, so it differs from NOW by
30// less than one full day and is itself a whole number of days.
31func TestTodayTruncatesToMidnight(t *testing.T) {
32 env := pinnedEnv(time.Date(2026, 8, 30, 15, 30, 0, 0, time.UTC))
33 v := Eval(mustParse(t, "TODAY()"), env)
34 if v.Kind != KindNum {
35 t.Fatalf("TODAY() Kind = %v, want KindNum", v.Kind)
36 }
37 if v.Num != float64(int64(v.Num)) {
38 t.Fatalf("TODAY() = %v, want a whole number of days", v.Num)
39 }
40 now := Eval(mustParse(t, "NOW()"), env)
41 if now.Num-v.Num >= 1 || now.Num-v.Num < 0 {
42 t.Fatalf("NOW()-TODAY() = %v, want in [0,1)", now.Num-v.Num)
43 }
44}
45
46func TestNowTodayRejectArguments(t *testing.T) {
47 env := pinnedEnv(time.Now())
48 for _, formula := range []string{"NOW(1)", "TODAY(1)"} {
49 v := Eval(mustParse(t, formula), env)
50 if v.Kind != KindErr || v.Err != ErrValue {
51 t.Errorf("with an argument = %v, want #VALUE!", v)
52 }
53 }
54}
55