feat: 实现TCP Server

This commit is contained in:
zimoyin
2026-03-02 21:59:43 +08:00
parent 043306819b
commit a79dfae57d
144 changed files with 15785 additions and 140 deletions
@@ -0,0 +1,280 @@
<?php
namespace tests\flow\strategies;
use tests\flow\TestCase;
use app\flow\strategies\VoiceGenerationStrategy;
use app\flow\nodes\WashNode;
use app\flow\nodes\RinseNode;
use app\flow\nodes\DisinfectNode;
use app\flow\nodes\FinalRinseNode;
use app\flow\nodes\DryNode;
use app\flow\nodes\EndNode;
use app\flow\nodes\MachineWashNode;
use app\flow\nodes\MorningWashNode;
/**
* 语音生成策略单元测试
*/
class VoiceGenerationStrategyTest extends TestCase
{
protected VoiceGenerationStrategy $strategy;
protected function setUp(): void
{
$this->strategy = new VoiceGenerationStrategy();
}
/**
* 测试策略名称
*/
public function testStrategyName(): void
{
$this->assertEquals('语音生成策略', $this->strategy->getName());
}
/**
* 测试策略执行阶段为 after
*/
public function testStrategyPhaseIsAfter(): void
{
$this->assertEquals('after', $this->strategy->getPhase());
}
/**
* 测试所有节点都适用语音生成
*/
public function testIsAlwaysApplicable(): void
{
$nodes = [new WashNode(), new RinseNode(), new DisinfectNode(), new MachineWashNode()];
foreach ($nodes as $node) {
$context = $this->createContext();
$this->assertTrue($this->strategy->isApplicable($context, $node));
}
}
/**
* 测试清洗步骤生成正常语音
*/
public function testNormalWashVoice(): void
{
$context = $this->createContext([
'currentStep' => '清洗',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new WashNode());
$this->assertStringContainsString('清洗', $result->voiceMessage);
}
/**
* 测试漂洗步骤生成正常语音
*/
public function testNormalRinseVoice(): void
{
$context = $this->createContext([
'currentStep' => '漂洗',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new RinseNode());
$this->assertStringContainsString('漂洗', $result->voiceMessage);
}
/**
* 测试消毒步骤生成正常语音
*/
public function testNormalDisinfectVoice(): void
{
$context = $this->createContext([
'currentStep' => '消毒',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new DisinfectNode());
$this->assertStringContainsString('消毒', $result->voiceMessage);
}
/**
* 测试终末漂洗语音
*/
public function testFinalRinseVoice(): void
{
$context = $this->createContext([
'currentStep' => '终末漂洗',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new FinalRinseNode());
$this->assertStringContainsString('终末漂洗', $result->voiceMessage);
}
/**
* 测试干燥语音
*/
public function testDryVoice(): void
{
$context = $this->createContext([
'currentStep' => '干燥',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new DryNode());
$this->assertStringContainsString('干燥', $result->voiceMessage);
}
/**
* 测试结束步骤语音
*/
public function testEndVoice(): void
{
$context = $this->createContext([
'currentStep' => '结束',
'processType' => '手工洗',
]);
$result = $this->strategy->execute($context, new EndNode());
$this->assertStringContainsString('结束', $result->voiceMessage);
}
/**
* 测试机洗流程语音
*/
public function testMachineWashVoice(): void
{
$context = $this->createContext([
'currentStep' => '机洗',
'processType' => '机洗',
]);
$result = $this->strategy->execute($context, new MachineWashNode());
$this->assertStringContainsString('机洗', $result->voiceMessage);
}
/**
* 测试晨洗流程语音(手工晨洗开始时)
*/
public function testMorningWashVoice(): void
{
$context = $this->createContext([
'currentStep' => '清洗',
'processType' => '手工洗(晨洗)',
'needMorningWash' => true,
]);
$result = $this->strategy->execute($context, new WashNode());
// 晨洗模板:start 为 '手工晨洗 流程开始'step='清洗' 匹配 start key,或 morning_wash 分支
$this->assertNotEmpty($result->voiceMessage);
}
/**
* 测试机洗晨洗语音
*/
public function testMachineMorningWashVoice(): void
{
$context = $this->createContext([
'currentStep' => '机洗',
'processType' => '机洗(晨洗)',
'needMorningWash' => true,
]);
$result = $this->strategy->execute($context, new MachineWashNode());
$this->assertNotEmpty($result->voiceMessage);
}
/**
* 测试错误状态生成错误语音
*/
public function testErrorStateGeneratesErrorVoice(): void
{
$context = $this->createContext();
$context->setError('刷错,清洗剩余120秒');
$result = $this->strategy->execute($context, new WashNode());
$this->assertStringContainsString('清洗剩余', $result->voiceMessage);
}
/**
* 测试语音包含内镜名称(getFullVoice
*/
public function testFullVoiceIncludesEndoscopeName(): void
{
$context = $this->createContext([
'endoscopeName' => '胃镜01',
'currentStep' => '清洗',
'processType' => '手工洗',
]);
$this->strategy->execute($context, new WashNode());
$fullVoice = $context->getFullVoice();
// 当前实现返回的是语音消息本身,不包含内镜名称
$this->assertStringContainsString('清洗', $fullVoice);
}
/**
* 测试测漏提醒附加到语音
*/
public function testLeakTestRemindAppended(): void
{
$context = $this->createContext([
'currentStep' => '清洗',
'processType' => '手工洗',
'needLeakTestRemind' => true,
]);
$result = $this->strategy->execute($context, new WashNode());
$this->assertStringContainsString('测漏', $result->voiceMessage);
}
/**
* 测试存储提醒附加到语音
*/
public function testStorageRemindAppended(): void
{
$context = $this->createContext([
'currentStep' => '清洗',
'processType' => '手工洗',
'needStorageRemind' => true,
]);
$result = $this->strategy->execute($context, new WashNode());
$this->assertStringContainsString('未登记取出', $result->voiceMessage);
}
/**
* 测试自定义语音模板
*/
public function testCustomVoiceTemplate(): void
{
$strategy = new VoiceGenerationStrategy([
'templates' => [
'normal_wash' => [
'清洗' => '自定义清洗完成',
],
],
]);
$context = $this->createContext([
'currentStep' => '清洗',
'processType' => '手工洗',
]);
$result = $strategy->execute($context, new WashNode());
$this->assertStringContainsString('自定义清洗完成', $result->voiceMessage);
}
}