Files
erqiwang_youle/client/tests/test_handlers_play.js
T
joywayerandClaude Opus 5 47c8a27d0d 二七王:补全出牌 handler 测试里 chupai3 各用例的 turn.seat 断言
三条 chupai3 用例(不带 grade 那条、跨包累加的两条)之前都带了 nextseat
字段却没验证它,读起来像遗漏,也让"chupai3 同样会推进控制权"这件事只被
验证了一次。补齐后四条 chupai3 用例均验证 turn.seat;跨包累加的两条从
turn.seat 由 0 变 1,顺带证明了第二个包确实被处理,不只是看 grade 一个数字。

只改测试文件,PlayHandler.js 未改动。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:01:56 +08:00

92 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 出牌 handler(chupai1/2/3)
const { load } = require('./_load');
const t = require('./_assert')();
load('client/js/gameabc-framework/system/EventBus.js');
load('client/js/01_SubGame/codes/state/Events.js');
load('client/js/01_SubGame/codes/state/GameState.js');
load('client/js/01_SubGame/codes/net/handlers/PlayHandler.js');
const S = EQW_GameState;
const evts = [];
Object.keys(EQW_Events).forEach(k => EventBus.on(EQW_Events[k], () => evts.push(k)));
// ================= chupai1(首家出牌,自己出的)=================
S.reset(); S.room.mySeat = 0; S.my.cards = [1,2,3,4]; evts.length = 0;
EQW_PlayHandler.handle({ success: true, seat: 0, cards: [1,2], count: 2, flower: 3,
cardtype: 201, nextseat: 1, countdown: 15, baozhu: 0,
cardsinhand: [3,4], curmultiple: 2,
seatlist: [[0,0,0,0,[5,2]],[0,0,0,0,[6,1]],[0,0,0,0,[7,3]]] }, 1);
t.eq('出牌者手牌被更新', S.my.cards, [3,4]);
t.eq('下一个出牌者', S.turn.seat, 1);
t.eq('倒计时', S.turn.countdown, 15);
t.eq('抓分倍数', S.aset.curmultiple, 2);
t.eq('牌况表', S.table.seatlist.length, 3);
t.eq('出牌发事件', evts.indexOf('EQW_CARD_PLAYED') >= 0, true);
// ================= chupai2(别人出牌)=================
// 别人出牌时没有 cardsinhand,不能抹掉自己的手牌
S.reset(); S.room.mySeat = 0; S.my.cards = [3,4]; evts.length = 0;
EQW_PlayHandler.handle({ success: true, seat: 1, cards: [5,6], nextseat: 2,
countdown: 15, baozhu: 0 }, 2);
t.eq('别人出牌不抹自己手牌', S.my.cards, [3,4]);
t.eq('控制权推进', S.turn.seat, 2);
// mustcard 只发给下一个出牌者
S.reset(); S.room.mySeat = 2;
EQW_PlayHandler.handle({ success: true, seat: 1, cards: [5,6], nextseat: 2,
countdown: 15, mustcard: [7,8] }, 2);
t.eq('必出牌', S.my.mustCard, [7,8]);
// 没有 mustcard 时要清空——否则上一轮的建议会残留
S.reset(); S.my.mustCard = [7,8];
EQW_PlayHandler.handle({ success: true, seat: 1, cards: [5,6], nextseat: 0, countdown: 15 }, 2);
t.eq('无 mustcard 时清空', S.my.mustCard, []);
// ================= chupai3(末家出牌,本轮结束)=================
// 真实的 chupai3 也带 nextseat(下一轮首家):服务端在 switch 前统一设置,
// 只有整轮结束进入结算时才会整体换成 jiesuan rpc(不会以 chupai3 到达 handler)
S.reset(); evts.length = 0;
EQW_PlayHandler.handle({ success: true, seat: 2, cards: [9,10], maxseat: 0, grade: 25,
nextseat: 0, countdown: 15, baozhu: 1, curmultiple: -2 }, 3);
t.eq('本轮最大者', S.result.chupai.maxseat, 0);
t.eq('本轮闲家得分', S.result.chupai.grade, 25);
t.eq('累计捡分', S.aset.grade, 25);
t.eq('报无主标志', S.aset.baozhu, 1);
t.eq('抓分倍数(带符号)', S.aset.curmultiple, -2);
t.eq('下一轮首家', S.turn.seat, 0);
t.eq('本轮结束发事件', evts.indexOf('EQW_TRICK_END') >= 0, true);
// 本轮闲家没得分时不带 grade,累计分不该被抹
S.reset(); S.aset.grade = 40;
EQW_PlayHandler.handle({ success: true, seat: 2, cards: [9,10], maxseat: 1,
nextseat: 1, countdown: 15 }, 3);
t.eq('无 grade 时累计分保持', S.aset.grade, 40);
t.eq('无 grade 时仍推进控制权', S.turn.seat, 1);
// grade 是「本轮」得分,要跨包累加进小局捡分,不是赋值——
// 若实现改成 aset.grade = data.grade,这条会把 25 覆盖成 15 而非累加到 25
S.reset();
EQW_PlayHandler.handle({ success: true, seat: 2, cards: [1,2], maxseat: 0, grade: 10,
nextseat: 0, countdown: 15 }, 3);
t.eq('第一轮捡分', S.aset.grade, 10);
t.eq('第一轮下一轮首家', S.turn.seat, 0);
EQW_PlayHandler.handle({ success: true, seat: 2, cards: [3,4], maxseat: 1, grade: 15,
nextseat: 1, countdown: 15 }, 3);
t.eq('第二轮跨包累加捡分', S.aset.grade, 25);
t.eq('第二轮下一轮首家(证明第二个包确被处理)', S.turn.seat, 1);
// ================= 甩错 =================
S.reset(); evts.length = 0;
EQW_PlayHandler.handle({ success: true, seat: 0, cards: [11], shuaicuo: 1, count: 1,
flower: 3, cardtype: 101, nextseat: 1, countdown: 15 }, 1);
t.eq('甩错标志', S.table.playproc.shuaicuo, 1);
// ================= 缺必需字段 =================
S.reset();
EQW_PlayHandler.handle({ success: true, cards: [1] }, 1); //缺 seat
t.eq('缺 seat 时跳过该包', S.turn.seat, -1);
process.exit(t.done('handlers_play') ? 0 : 1);