MCPcopy Create free account
hub / github.com/Facets-cloud/flow / TestBuildStatsWindowed

Function TestBuildStatsWindowed

internal/stats/report_test.go:79–131  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

77}
78
79func TestBuildStatsWindowed(t *testing.T) {
80 root := t.TempDir()
81 claudeProj := t.TempDir()
82
83 db, err := flowdb.OpenDB(filepath.Join(root, "flow.db"))
84 if err != nil {
85 t.Fatal(err)
86 }
87 defer db.Close()
88 work := "/work/app"
89 mustExec(t, db, `INSERT INTO tasks (slug,name,status,work_dir,session_id,created_at,updated_at)
90 VALUES ('t1','T1','done',?, '00000000-0000-4000-8000-000000000001', '2026-05-01T00:00:00Z','2026-05-01T00:00:00Z')`, work)
91
92 jdir := filepath.Join(claudeProj, claude.EncodeCwd(work))
93 os.MkdirAll(jdir, 0o755)
94 // (a) lookup BEFORE the cutoff, (b) lookup AFTER the cutoff,
95 // (c) lookup with a missing timestamp (zero TS).
96 before := `{"type":"assistant","timestamp":"2026-05-01T10:00:00.000Z","message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"flow show task"}}]}}`
97 after := `{"type":"assistant","timestamp":"2026-06-10T10:00:00.000Z","message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"flow show task"}}]}}`
98 noTS := `{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"flow show task"}}]}}`
99 os.WriteFile(filepath.Join(jdir, "00000000-0000-4000-8000-000000000001.jsonl"),
100 []byte(before+"\n"+after+"\n"+noTS+"\n"), 0o644)
101
102 // Brief + updates for t1 — known byte sizes for the windowed token assertion.
103 // All three lookups are resumes, so each in-window resume contributes
104 // briefBytes + updatesBytes. Only the after-cutoff one is in window.
105 briefContent := []byte("# T1 brief\nWindowed test brief.\n") // 32 bytes
106 updatesContent := []byte("# update\nWindowed update note.\n") // 31 bytes
107 os.MkdirAll(filepath.Join(root, "tasks", "t1", "updates"), 0o755)
108 os.WriteFile(filepath.Join(root, "tasks", "t1", "brief.md"), briefContent, 0o644)
109 os.WriteFile(filepath.Join(root, "tasks", "t1", "updates", "u1.md"), updatesContent, 0o644)
110
111 c := LoadCache(filepath.Join(root, "stats-cache.json"))
112 since := time.Date(2026, 6, 1, 0, 0, 0, 0, time.UTC) // between (a) and (b)
113 s, err := BuildStats(BuildOpts{
114 Root: root, ClaudeProjects: claudeProj, DB: db, Cache: c,
115 Constants: DefaultConstants(), Since: since, Project: "",
116 })
117 if err != nil {
118 t.Fatal(err)
119 }
120 // Only the after-cutoff lookup is counted; zero-TS and before-cutoff excluded.
121 if s.LookupsTotal != 1 || s.LookupsByKind[LookupResume] != 1 {
122 t.Errorf("windowed lookups = %d %v, want 1 resume", s.LookupsTotal, s.LookupsByKind)
123 }
124 // The window guard must govern byte accumulation too: only the single
125 // in-window resume contributes; out-of-window and zero-TS contribute ZERO.
126 wantContextTokens := (int64(len(briefContent)) + int64(len(updatesContent))) / 4
127 if s.Savings.ContextTokens != wantContextTokens {
128 t.Errorf("windowed ContextTokens = %d, want %d (only the 1 in-window resume: (brief=%d + updates=%d)/4)",
129 s.Savings.ContextTokens, wantContextTokens, len(briefContent), len(updatesContent))
130 }
131}
132
133func TestBuildStatsPlaybookRuns(t *testing.T) {
134 root := t.TempDir()

Callers

nothing calls this directly

Calls 6

OpenDBFunction · 0.92
EncodeCwdFunction · 0.92
mustExecFunction · 0.85
LoadCacheFunction · 0.85
BuildStatsFunction · 0.85
DefaultConstantsFunction · 0.85

Tested by

no test coverage detected