Files
xzmaster/backend/src/test/java/com/xuezhanmaster/game/event/GameEventTest.java
hujun 36dcfb7d31 feat: 实现麻将游戏结算系统与自摸胡功能
新增结算类型枚举和分数变更记录模型
补全响应裁决器与结算服务,支持点炮胡、自摸胡和明杠结算
扩展座位模型,增加已胡状态和分数字段
完善胡牌评估器,支持自摸胡判断
前端原型页增加分数显示和已胡状态
更新SPRINT文档记录当前进度
2026-03-20 13:58:16 +08:00

98 lines
3.6 KiB
Java

package com.xuezhanmaster.game.event;
import com.xuezhanmaster.game.domain.ActionType;
import com.xuezhanmaster.game.domain.ScoreChange;
import com.xuezhanmaster.game.domain.SettlementResult;
import com.xuezhanmaster.game.domain.SettlementType;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class GameEventTest {
@Test
void shouldBuildResponseActionPayloadForFutureResponseEvents() {
GameEvent event = GameEvent.responseActionDeclared(
"game-1",
GameEventType.PENG_DECLARED,
2,
1,
"三万"
);
assertThat(event.eventType()).isEqualTo(GameEventType.PENG_DECLARED);
assertThat(event.seatNo()).isEqualTo(2);
assertThat(event.payload())
.containsEntry("actionType", "PENG")
.containsEntry("sourceSeatNo", 1)
.containsEntry("tile", "三万");
}
@Test
void shouldBuildStandardPublicTableEvents() {
GameEvent started = GameEvent.gameStarted("game-1", "room-1");
GameEvent phaseChanged = GameEvent.phaseChanged("game-1", "PLAYING");
GameEvent switched = GameEvent.turnSwitched("game-1", 3);
assertThat(started.eventType()).isEqualTo(GameEventType.GAME_STARTED);
assertThat(started.payload()).containsEntry("roomId", "room-1");
assertThat(phaseChanged.eventType()).isEqualTo(GameEventType.GAME_PHASE_CHANGED);
assertThat(phaseChanged.payload()).containsEntry("phase", "PLAYING");
assertThat(switched.eventType()).isEqualTo(GameEventType.TURN_SWITCHED);
assertThat(switched.payload()).containsEntry("currentSeatNo", 3);
}
@Test
void shouldBuildSettlementEvents() {
SettlementResult settlementResult = new SettlementResult(
SettlementType.DIAN_PAO_HU,
ActionType.HU,
2,
0,
"9筒",
List.of(
new ScoreChange(2, 1, 3),
new ScoreChange(0, -1, -2)
)
);
GameEvent settlementApplied = GameEvent.settlementApplied("game-1", settlementResult);
GameEvent scoreChanged = GameEvent.scoreChanged("game-1", 2, SettlementType.DIAN_PAO_HU.name(), 1, 3);
assertThat(settlementApplied.eventType()).isEqualTo(GameEventType.SETTLEMENT_APPLIED);
assertThat(settlementApplied.payload())
.containsEntry("settlementType", "DIAN_PAO_HU")
.containsEntry("actionType", "HU")
.containsEntry("sourceSeatNo", 0)
.containsEntry("triggerTile", "9筒");
assertThat(settlementApplied.payload()).containsKey("scoreChanges");
assertThat(scoreChanged.eventType()).isEqualTo(GameEventType.SCORE_CHANGED);
assertThat(scoreChanged.payload())
.containsEntry("settlementType", "DIAN_PAO_HU")
.containsEntry("delta", 1)
.containsEntry("score", 3);
}
@Test
void shouldAllowHuEventWithoutSourceSeatForSelfDraw() {
GameEvent selfDrawHu = GameEvent.responseActionDeclared(
"game-1",
GameEventType.HU_DECLARED,
0,
null,
null
);
assertThat(selfDrawHu.eventType()).isEqualTo(GameEventType.HU_DECLARED);
assertThat(selfDrawHu.payload())
.containsEntry("actionType", "HU")
.doesNotContainKey("sourceSeatNo")
.doesNotContainKey("tile");
}
}