1package daemon
2
3import (
4 "testing"
5
6 "github.com/bnema/vev/internal/domain"
7 "github.com/bnema/vev/internal/protocol"
8 "github.com/stretchr/testify/require"
9)
10
11func TestSharedPTYGeometryCharacterization(t *testing.T) {
12 tests := []struct {
13 name string
14 run func(*testing.T)
15 }{
16 {
17 name: "rejected claim restores most recent remaining attachment",
18 run: func(t *testing.T) {
19 sess := &session{}
20 first := &attachedClient{}
21 first.setGeometry(domain.Geometry{
22 Size: domain.Size{Cols: 80, Rows: 24}, PixelWidth: 800, PixelHeight: 480,
23 })
24 second := &attachedClient{}
25 second.setGeometry(domain.Geometry{
26 Size: domain.Size{Cols: 100, Rows: 30}, PixelWidth: 1000, PixelHeight: 600,
27 })
28 require.True(t, sess.registerAttachment(first))
29 require.True(t, sess.registerAttachment(second))
30
31 claim, claimed := sess.geometry.claimSize(sess, second, domain.Size{Cols: 120, Rows: 40})
32 require.True(t, claimed)
33 sess.geometry.release(sess, claim)
34
35 source, ok := sess.geometry.sourceSnapshot(sess)
36 require.True(t, ok)
37 require.Same(t, first, source.attachment)
38 require.Equal(t, first.geometrySnapshot(), source.geometry)
39 },
40 },
41 {
42 name: "losing shared claim retains attachment local geometry",
43 run: func(t *testing.T) {
44 pty, releasePTY := newBlockingPTY(t)
45 t.Cleanup(releasePTY)
46 d := newTestDaemon(t, newFactory(t, pty), stubClock{})
47 firstTransport, _ := newCapturingTransport(t)
48 sess, first, err := d.route(protocol.Hello{
49 Version: protocol.Version, Intent: protocol.IntentNew, Name: "work",
50 Size: domain.Size{Cols: 80, Rows: 24}, ClientID: [16]byte{1},
51 }, firstTransport)
52 require.NoError(t, err)
53 secondTransport, _ := newCapturingTransport(t)
54 _, second, err := d.route(protocol.Hello{
55 Version: protocol.Version, Intent: protocol.IntentAttach, Name: "work",
56 Size: domain.Size{Cols: 100, Rows: 40}, ClientID: [16]byte{2},
57 }, secondTransport)
58 require.NoError(t, err)
59
60 rc := sess.renderCoordinator()
61 lease := rc.attachmentLease(second)
62 require.True(t, rc.markAttachmentReady(lease))
63 token := sess.captureAttachmentCapability(second, secondTransport)
64 token.lease = lease
65 second.installTestAttachmentCapability(token)
66 effect, admitted := second.beginAttachmentEffect(token)
67 require.True(t, admitted)
68 defer effect.End()
69
70 requested := domain.Geometry{
71 Size: domain.Size{Cols: 120, Rows: 50}, PixelWidth: 1200, PixelHeight: 1000,
72 }
73 var superseded bool
74 d.beforeSessionResizePublication = func() {
75 if superseded {
76 return
77 }
78 superseded = true
79 _, claimed := sess.geometry.claimAttachment(sess, first)
80 require.True(t, claimed)
81 }
82 d.resizeAttachmentGeometryForLease(effect, requested)
83
84 require.Equal(t, requested, second.geometrySnapshot(), "a losing shared claim must retain its Attachment-local window")
85 source, ok := sess.geometry.sourceSnapshot(sess)
86 require.True(t, ok)
87 require.Same(t, first, source.attachment)
88 },
89 },
90 }
91
92 for _, tt := range tests {
93 t.Run(tt.name, tt.run)
94 }
95}