返回 DeepSeek-Reasonix
fake_test.go
根目录 / internal / extension / dispatch / fake_test.go
1 package dispatch
2
3 import (
4 "context"
5 "encoding/json"
6 "strings"
7 "sync"
8 "time"
9
10 "reasonix/internal/extension/protocol"
11 )
12
13 // recordedCall captures one intercept or event call a fake client received.
14 type recordedCall struct {
15 event protocol.InterceptEvent
16 payload json.RawMessage
17 }
18
19 // fakeClient is a scriptable dispatch.Client for tests. Nil hooks answer
20 // continue (intercept) or success (notify).
21 type fakeClient struct {
22 mu sync.Mutex
23 interceptFn func(event protocol.InterceptEvent, payload json.RawMessage) (protocol.InterceptResult, error)
24 notifyFn func(event protocol.InterceptEvent, payload json.RawMessage) error
25 intercepts []recordedCall
26 notifies []recordedCall
27 }
28
29 func (f *fakeClient) Intercept(_ context.Context, event protocol.InterceptEvent, payload json.RawMessage, _ time.Duration) (protocol.InterceptResult, error) {
30 f.mu.Lock()
31 f.intercepts = append(f.intercepts, recordedCall{event: event, payload: append(json.RawMessage(nil), payload...)})
32 fn := f.interceptFn
33 f.mu.Unlock()
34 if fn == nil {
35 return protocol.InterceptResult{Decision: protocol.DecisionContinue}, nil
36 }
37 return fn(event, payload)
38 }
39
40 func (f *fakeClient) TryNotifyEvent(event protocol.InterceptEvent, payload json.RawMessage) error {
41 f.mu.Lock()
42 f.notifies = append(f.notifies, recordedCall{event: event, payload: append(json.RawMessage(nil), payload...)})
43 fn := f.notifyFn
44 f.mu.Unlock()
45 if fn == nil {
46 return nil
47 }
48 return fn(event, payload)
49 }
50
51 func (f *fakeClient) interceptCount() int {
52 f.mu.Lock()
53 defer f.mu.Unlock()
54 return len(f.intercepts)
55 }
56
57 func (f *fakeClient) notifyCount() int {
58 f.mu.Lock()
59 defer f.mu.Unlock()
60 return len(f.notifies)
61 }
62
63 // observedPayloads returns copies of every payload Intercept was called with.
64 func (f *fakeClient) observedPayloads() []json.RawMessage {
65 f.mu.Lock()
66 defer f.mu.Unlock()
67 out := make([]json.RawMessage, len(f.intercepts))
68 for i, call := range f.intercepts {
69 out[i] = call.payload
70 }
71 return out
72 }
73
74 // warnRecorder collects Options.Warn messages, safe for concurrent use.
75 type warnRecorder struct {
76 mu sync.Mutex
77 msgs []string
78 }
79
80 func (w *warnRecorder) warn(msg string) {
81 w.mu.Lock()
82 defer w.mu.Unlock()
83 w.msgs = append(w.msgs, msg)
84 }
85
86 func (w *warnRecorder) count() int {
87 w.mu.Lock()
88 defer w.mu.Unlock()
89 return len(w.msgs)
90 }
91
92 func (w *warnRecorder) contains(substr string) bool {
93 w.mu.Lock()
94 defer w.mu.Unlock()
95 for _, msg := range w.msgs {
96 if strings.Contains(msg, substr) {
97 return true
98 }
99 }
100 return false
101 }
102
102 lines GO