11package top.ellan.mahjong.table.render
22
3- import top.ellan.mahjong.model.SeatWind
4- import top.ellan.mahjong.render.scene.MeldView
5- import top.ellan.mahjong.table.core.MahjongTableSession
63import org.bukkit.Location
74import org.bukkit.entity.Player
85import org.mockito.ArgumentMatchers
@@ -11,26 +8,39 @@ import org.mockito.Mockito.mock
118import org.mockito.Mockito.never
129import org.mockito.Mockito.verify
1310import org.mockito.Mockito.`when`
11+ import top.ellan.mahjong.model.SeatWind
12+ import top.ellan.mahjong.render.scene.MeldView
13+ import top.ellan.mahjong.table.core.MahjongTableSession
1414import java.util.UUID
1515import kotlin.test.Test
1616import kotlin.test.assertEquals
1717import kotlin.test.assertTrue
1818
1919class TableRenderSnapshotFactoryTest {
2020 @Test
21- fun `render snapshot reuses precomputed online viewers ` () {
21+ fun `render snapshot preserves serialized viewer ordering and membership ` () {
2222 val session = mock(MahjongTableSession ::class .java)
2323 val factory = TableRenderSnapshotFactory ()
2424
2525 val eastId = UUID .fromString(" 00000000-0000-0000-0000-000000000011" )
26- val southId = UUID .fromString(" 00000000-0000-0000-0000-000000000012" )
26+ val southId = UUID .fromString(" 80000000-0000-0000-0000-000000000012" )
27+ val westId = UUID .fromString(" 7fffffff-ffff-ffff-ffff-ffffffffffff" )
28+ val northId = UUID .fromString(" 00000000-0000-0000-0000-000000000014" )
2729 val eastViewer = mock(Player ::class .java)
30+ val duplicateEastViewer = mock(Player ::class .java)
2831 val southViewer = mock(Player ::class .java)
32+ val westViewer = mock(Player ::class .java)
2933
34+ assertTrue(southId.compareTo(eastId) < 0 )
35+ assertTrue(southId.toString().compareTo(eastId.toString()) > 0 )
3036 `when `(eastViewer.uniqueId).thenReturn(eastId)
37+ `when `(duplicateEastViewer.uniqueId).thenReturn(eastId)
3138 `when `(southViewer.uniqueId).thenReturn(southId)
39+ `when `(westViewer.uniqueId).thenReturn(westId)
3240 `when `(session.center()).thenReturn(Location (null , 0.0 , 64.0 , 0.0 ))
33- `when `(session.viewers()).thenReturn(listOf (eastViewer, southViewer))
41+ `when `(session.viewers()).thenReturn(
42+ listOf (southViewer, westViewer, duplicateEastViewer, eastViewer),
43+ )
3444 `when `(session.isStarted()).thenReturn(false )
3545 `when `(session.isRoundFinished()).thenReturn(false )
3646 `when `(session.remainingWallCount()).thenReturn(0 )
@@ -49,8 +59,8 @@ class TableRenderSnapshotFactoryTest {
4959 `when `(session.doraIndicators()).thenReturn(emptyList())
5060 `when `(session.playerAt(SeatWind .EAST )).thenReturn(eastId)
5161 `when `(session.playerAt(SeatWind .SOUTH )).thenReturn(southId)
52- `when `(session.playerAt(SeatWind .WEST )).thenReturn(null )
53- `when `(session.playerAt(SeatWind .NORTH )).thenReturn(null )
62+ `when `(session.playerAt(SeatWind .WEST )).thenReturn(westId )
63+ `when `(session.playerAt(SeatWind .NORTH )).thenReturn(northId )
5464
5565 doAnswer { invocation ->
5666 (invocation.arguments[0 ] as UUID ? )?.toString() ? : " "
@@ -61,7 +71,7 @@ class TableRenderSnapshotFactoryTest {
6171 `when `(session.stickLayoutCount(wind)).thenReturn(0 )
6272 `when `(session.cornerSticks(wind)).thenReturn(emptyList())
6373 }
64- for (playerId in listOf (eastId, southId)) {
74+ for (playerId in listOf (eastId, southId, westId, northId )) {
6575 `when `(session.points(playerId)).thenReturn(25000 )
6676 `when `(session.isRiichi(playerId)).thenReturn(false )
6777 `when `(session.isReady(playerId)).thenReturn(false )
@@ -77,13 +87,30 @@ class TableRenderSnapshotFactoryTest {
7787 val snapshot = factory.create(session, 1L , 0L )
7888 val eastSeat = snapshot.seat(SeatWind .EAST )
7989 val southSeat = snapshot.seat(SeatWind .SOUTH )
90+ val westSeat = snapshot.seat(SeatWind .WEST )
91+ val northSeat = snapshot.seat(SeatWind .NORTH )
8092
8193 assertTrue(eastSeat.online())
8294 assertTrue(southSeat.online())
83- assertEquals(listOf (southId), eastSeat.viewerIdsExcluding())
84- assertEquals(listOf (eastId), southSeat.viewerIdsExcluding())
85- assertEquals(southId.toString(), eastSeat.viewerMembershipSignature())
86- assertEquals(eastId.toString(), southSeat.viewerMembershipSignature())
95+ assertTrue(westSeat.online())
96+ assertTrue(! northSeat.online())
97+ assertEquals(listOf (westId, southId), eastSeat.viewerIdsExcluding())
98+ assertEquals(listOf (eastId, westId), southSeat.viewerIdsExcluding())
99+ assertEquals(listOf (eastId, southId), westSeat.viewerIdsExcluding())
100+ assertTrue(northSeat.viewerIdsExcluding().isEmpty())
101+ assertEquals(
102+ " 7fffffff-ffff-ffff-ffff-ffffffffffff80000000-0000-0000-0000-000000000012" ,
103+ eastSeat.viewerMembershipSignature(),
104+ )
105+ assertEquals(
106+ " 00000000-0000-0000-0000-0000000000117fffffff-ffff-ffff-ffff-ffffffffffff" ,
107+ southSeat.viewerMembershipSignature(),
108+ )
109+ assertEquals(
110+ " 00000000-0000-0000-0000-00000000001180000000-0000-0000-0000-000000000012" ,
111+ westSeat.viewerMembershipSignature(),
112+ )
113+ assertTrue(northSeat.viewerMembershipSignature().isEmpty())
87114
88115 verify(session, never()).onlinePlayer(ArgumentMatchers .any(UUID ::class .java))
89116 verify(session, never()).viewerIdsExcluding(ArgumentMatchers .any(UUID ::class .java))
@@ -123,7 +150,12 @@ class TableRenderSnapshotFactoryTest {
123150 val snapshot = factory.create(session, 1L , 0L )
124151
125152 assertTrue(snapshot.doraIndicators().isEmpty())
153+ for (wind in SeatWind .values()) {
154+ val seat = snapshot.seat(wind)
155+ assertTrue(! seat.online())
156+ assertTrue(seat.viewerIdsExcluding().isEmpty())
157+ assertTrue(seat.viewerMembershipSignature().isEmpty())
158+ }
126159 verify(session, never()).doraIndicators()
127160 }
128161}
129-
0 commit comments