Files
zyt/server/tests/RevisitVisitSlotServiceTest.php
T
2026-10-15 11:03:54 +08:00

68 lines
3.4 KiB
PHP
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.
<?php
declare(strict_types=1);
/**
* 诊次服务(RevisitVisitSlotService)纯函数单测,不连库。
* php server/tests/RevisitVisitSlotServiceTest.php
* 覆盖:slotBefore 严格小于边界(同一秒订单不计入)、偏移钳制、resolveRevisitSlotStartOffset、
* 与 RevisitRateLogic 持有人规则(t <= ct 归新持有人)的对偶关系。
*/
require dirname(__DIR__) . '/vendor/autoload.php';
use app\common\service\tcm\RevisitVisitSlotService as S;
$checks = 0;
function expect(bool $condition, string $message): void
{
global $checks;
if (!$condition) {
fwrite(STDERR, "FAIL: {$message}\n");
exit(1);
}
$checks++;
}
$t = static fn (string $dt): int => (int) strtotime($dt);
$orders = [$t('2026-05-03 10:00:00'), $t('2026-06-12 10:00:00'), $t('2026-08-20 10:00:00')];
// ---------- slotBefore 基本 ----------
expect(S::slotBefore($orders, 0, $t('2026-09-10 10:00:00')) === 3, '三笔订单之后继承 → k=3');
expect(S::slotBefore($orders, 0, $t('2026-07-01 00:00:00')) === 2, '两笔之后 → k=2');
expect(S::slotBefore($orders, 0, $t('2026-05-03 09:59:59')) === 0, '首单之前 → k=0');
expect(S::slotBefore([], 0, $t('2026-09-10 10:00:00')) === 0, '无订单 → k=0');
expect(S::slotBefore([], 1, $t('2026-09-10 10:00:00')) === 1, '无订单有偏移 → k=offset');
// ---------- 严格小于:同一秒 ----------
expect(S::slotBefore($orders, 0, $t('2026-08-20 10:00:00')) === 2, '同一秒订单视为「指派之后」,不计入 k');
expect(S::slotBefore($orders, 0, $t('2026-08-20 10:00:01')) === 3, '晚一秒即计入');
// 对偶:持有人规则 t <= ct 归新持有人(RevisitRateLogic.php 指针 while tl[ptr].t <= ct)
$assignTs = $t('2026-08-20 10:00:00');
$orderCt = $t('2026-08-20 10:00:00');
expect(($assignTs <= $orderCt) && S::slotBefore([$orderCt], 0, $assignTs) === 0, '同一秒:订单归新持有人且不计入 k(对偶成立)');
// ---------- 偏移 ----------
expect(S::slotBefore($orders, 2, $t('2026-09-10 10:00:00')) === 5, '偏移叠加');
expect(S::slotBefore($orders, -3, $t('2026-09-10 10:00:00')) === 3, '负偏移钳到 0');
expect(S::slotBefore($orders, 99, $t('2026-09-10 10:00:00')) === 23, '偏移上限 20');
expect(S::slotBefore(['1778000000', 1779000000], 0, 1778500000) === 1, '字符串时间戳可用');
// ---------- resolveRevisitSlotStartOffset ----------
$map = [1 => 0, 2 => 1, 3 => -5, 4 => 25, 5 => '2'];
expect(S::resolveRevisitSlotStartOffset(1, $map) === 0, 'offset 0');
expect(S::resolveRevisitSlotStartOffset(2, $map) === 1, 'offset 1');
expect(S::resolveRevisitSlotStartOffset(3, $map) === 0, '负值钳 0');
expect(S::resolveRevisitSlotStartOffset(4, $map) === S::MAX_OFFSET, '超限钳 20');
expect(S::resolveRevisitSlotStartOffset(5, $map) === 2, '字符串转 int');
expect(S::resolveRevisitSlotStartOffset(999, $map) === 0, '缺键默认 0');
// ---------- current_slot / next_slot 口径(与 batchCurrentSlot 组装一致) ----------
$validCount = \count($orders);
$offset = S::resolveRevisitSlotStartOffset(2, $map);
$currentSlot = $validCount + $offset;
expect($currentSlot === 4 && $currentSlot + 1 === 5, 'current_slot = |E(D)| + off(D),next_slot = current_slot + 1');
expect(S::slotBefore($orders, $offset, PHP_INT_MAX) === $currentSlot, '未来时刻的 slot_at 等于 current_slot');
echo "RevisitVisitSlotServiceTest OK ({$checks} checks)\n";