-
Notifications
You must be signed in to change notification settings - Fork 1
/
testjaws_test.go
121 lines (108 loc) · 2.64 KB
/
testjaws_test.go
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package jaws
import (
"bytes"
"context"
"html/template"
"log/slog"
"net/http"
"net/http/httptest"
"time"
)
type testJaws struct {
*Jaws
testtmpl *template.Template
log bytes.Buffer
}
func newTestJaws() (tj *testJaws) {
tj = &testJaws{
Jaws: New(),
}
tj.Jaws.Logger = slog.New(slog.NewTextHandler(&tj.log, nil))
tj.Jaws.MakeAuth = func(r *Request) Auth {
return defaultAuth{}
}
tj.testtmpl = template.Must(template.New("testtemplate").Parse(`{{with $.Dot}}<div id="{{$.Jid}}" {{$.Attrs}}>{{.}}</div>{{end}}`))
tj.AddTemplateLookuper(tj.testtmpl)
tj.Jaws.updateTicker = time.NewTicker(time.Millisecond)
go tj.Serve()
return
}
type testRequest struct {
hr *http.Request
rr *httptest.ResponseRecorder
jw *testJaws
readyCh chan struct{}
doneCh chan struct{}
inCh chan wsMsg
outCh chan wsMsg
bcastCh chan Message
ctx context.Context
cancel context.CancelFunc
expectPanic bool
panicked bool
panicVal any
*Request
RequestWriter
}
func (tj *testJaws) newRequest(hr *http.Request) (tr *testRequest) {
if hr == nil {
hr = httptest.NewRequest(http.MethodGet, "/", nil)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
hr = hr.WithContext(ctx)
rr := httptest.NewRecorder()
rr.Body = &bytes.Buffer{}
rq := tj.NewRequest(hr)
if rq == nil || tj.UseRequest(rq.JawsKey, hr) != rq {
panic("failed to create or use jaws.Request")
}
bcastCh := tj.subscribe(rq, 64)
for i := 0; i <= cap(tj.subCh); i++ {
tj.subCh <- subscription{} // ensure subscription is processed
}
tr = &testRequest{
hr: hr,
rr: rr,
jw: tj,
readyCh: make(chan struct{}),
doneCh: make(chan struct{}),
inCh: make(chan wsMsg),
outCh: make(chan wsMsg, cap(bcastCh)),
bcastCh: bcastCh,
ctx: ctx,
cancel: cancel,
Request: rq,
RequestWriter: rq.Writer(rr),
}
go func() {
defer func() {
if tr.expectPanic {
if tr.panicVal = recover(); tr.panicVal != nil {
tr.panicked = true
}
}
close(tr.doneCh)
}()
close(tr.readyCh)
tr.process(tr.bcastCh, tr.inCh, tr.outCh) // usubs from bcase, closes outCh
tr.jw.recycle(tr.Request)
}()
return
}
func (tr *testRequest) BodyString() string {
return tr.rr.Body.String()
}
func (tr *testRequest) BodyHTML() template.HTML {
return template.HTML(tr.BodyString())
}
func (tr *testRequest) Close() {
tr.cancel()
tr.jw.Close()
}
func (tr *testRequest) Write(buf []byte) (int, error) {
return tr.rr.Write(buf)
}
func newTestRequest() (tr *testRequest) {
tj := newTestJaws()
return tj.newRequest(nil)
}