▍ humdrum codex / ticktock v0.0.2
license AGPL-3.0
2.4 KB raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package activity

import (
	"os"
	"path/filepath"
	"testing"
	"time"

	"ticktock/internal/autotrack"
)

func TestLoadDayParsesAndSkipsMalformed(t *testing.T) {
	dir := t.TempDir()
	lines := `{"start": "2026-07-07T08:59:19", "end": "2026-07-07T09:00:09", "secs": 49, "app": "Trace", "title": "", "url": "", "domain": "", "idle": false}
this line is not json
{"start": "not-a-time", "end": "2026-07-07T09:10:00", "secs": 1, "app": "Bad", "title": "", "url": "", "domain": "", "idle": false}
{"start": "2026-07-07T09:30:00", "end": "2026-07-07T10:00:00", "secs": 1800, "app": "", "title": "", "url": "", "domain": "", "idle": true}
`
	if err := os.WriteFile(filepath.Join(dir, "activity-2026-07-07.jsonl"), []byte(lines), 0o644); err != nil {
		t.Fatal(err)
	}
	segs, err := LoadDay(dir, "2026-07-07")
	if err != nil {
		t.Fatalf("tolerant parse must not error: %v", err)
	}
	if len(segs) != 2 {
		t.Fatalf("want 2 valid segments (malformed skipped), got %d", len(segs))
	}
	want := time.Date(2026, 7, 7, 8, 59, 19, 0, time.Local)
	if segs[0].App != "Trace" || !segs[0].Start.Equal(want) {
		t.Errorf("seg0 = %+v", segs[0])
	}
	if !segs[1].Idle {
		t.Errorf("seg1 should be idle: %+v", segs[1])
	}
}

func TestLoadDayMissingFileIsEmptyNoError(t *testing.T) {
	segs, err := LoadDay(t.TempDir(), "2026-01-01")
	if err != nil || len(segs) != 0 {
		t.Fatalf("missing file ⇒ empty, nil; got %v, %v", segs, err)
	}
	segs, err = LoadDay("", "2026-01-01")
	if err != nil || len(segs) != 0 {
		t.Fatalf("empty dataDir ⇒ empty, nil; got %v, %v", segs, err)
	}
}

// Round-trip: what the writer persists, the reader loads back — the two
// halves of the port agree on the byte shape.
func TestRoundTripWithWriter(t *testing.T) {
	dir := t.TempDir()
	start := time.Date(2026, 7, 7, 9, 0, 0, 0, time.Local)
	seg := &autotrack.Segment{
		Ctx:   autotrack.Ctx{App: "Safari", Title: "GitHub", URL: "https://github.com/x", Domain: "github.com"},
		Start: start, End: start.Add(120 * time.Second),
	}
	if err := autotrack.WriteSegment(dir, seg, 15); err != nil {
		t.Fatal(err)
	}
	segs, err := LoadDay(dir, "2026-07-07")
	if err != nil || len(segs) != 1 {
		t.Fatalf("round trip failed: %v, %v", segs, err)
	}
	got := segs[0]
	if got.App != "Safari" || got.Domain != "github.com" || got.URL != "https://github.com/x" ||
		!got.Start.Equal(start) || !got.End.Equal(start.Add(120*time.Second)) || got.Idle {
		t.Errorf("round-trip mismatch: %+v", got)
	}
}