This commit is contained in:
root
2025-07-11 15:00:12 +08:00
parent 6b2083a8bb
commit ed2ef14718
10 changed files with 1183 additions and 3 deletions

View File

@@ -0,0 +1,339 @@
/**
* Python Core 测试页面
* 用于测试增强版Python Core的各项功能
*/
import React, { useState } from 'react'
import { invoke } from '@tauri-apps/api/tauri'
import { Play, CheckCircle, XCircle, Loader, RefreshCw } from 'lucide-react'
interface PythonResponse {
status: boolean
msg: string
data?: any
}
interface TestResult {
name: string
status: 'pending' | 'running' | 'success' | 'error'
response?: PythonResponse
error?: string
duration?: number
}
const PythonCoreTestPage: React.FC = () => {
const [testResults, setTestResults] = useState<TestResult[]>([])
const [isRunning, setIsRunning] = useState(false)
const tests = [
{
name: '基础功能测试',
command: 'test_python_core_basic',
description: '测试Python Core的基本功能和响应格式'
},
{
name: '模板管理测试',
command: 'test_template_manager',
description: '测试模板管理服务的功能'
},
{
name: '项目管理测试',
command: 'test_project_manager',
description: '测试项目管理服务的功能'
},
{
name: '文件管理测试',
command: 'test_file_manager',
description: '测试文件管理服务的功能',
params: { path: '.' }
},
{
name: 'AI视频测试',
command: 'test_ai_video',
description: '测试AI视频生成环境和功能'
},
{
name: '资源分类测试',
command: 'test_get_categories',
description: '测试资源分类管理功能'
},
{
name: '批量导入测试',
command: 'test_batch_import_templates',
description: '测试模板批量导入功能',
params: { folder_path: './templates' }
},
{
name: '创建项目测试',
command: 'test_create_project',
description: '测试项目创建功能',
params: { name: 'Test Project', description: 'A test project' }
}
]
const runSingleTest = async (test: any, index: number) => {
const startTime = Date.now()
// 更新状态为运行中
setTestResults(prev => {
const newResults = [...prev]
newResults[index] = {
name: test.name,
status: 'running'
}
return newResults
})
try {
let response: PythonResponse
if (test.params) {
response = await invoke(test.command, test.params)
} else {
response = await invoke(test.command)
}
const duration = Date.now() - startTime
// 更新状态为成功
setTestResults(prev => {
const newResults = [...prev]
newResults[index] = {
name: test.name,
status: 'success',
response,
duration
}
return newResults
})
} catch (error) {
const duration = Date.now() - startTime
// 更新状态为错误
setTestResults(prev => {
const newResults = [...prev]
newResults[index] = {
name: test.name,
status: 'error',
error: error as string,
duration
}
return newResults
})
}
}
const runAllTests = async () => {
setIsRunning(true)
// 初始化所有测试状态
setTestResults(tests.map(test => ({
name: test.name,
status: 'pending' as const
})))
// 逐个运行测试
for (let i = 0; i < tests.length; i++) {
await runSingleTest(tests[i], i)
// 在测试之间添加短暂延迟
await new Promise(resolve => setTimeout(resolve, 500))
}
setIsRunning(false)
}
const runComprehensiveTest = async () => {
setIsRunning(true)
try {
const startTime = Date.now()
const results: PythonResponse[] = await invoke('test_all_python_core_functions')
const duration = Date.now() - startTime
// 将综合测试结果映射到各个测试
const mappedResults = tests.map((test, index) => ({
name: test.name,
status: results[index]?.status ? 'success' : 'error' as const,
response: results[index],
duration: duration / tests.length // 平均分配时间
}))
setTestResults(mappedResults)
} catch (error) {
console.error('Comprehensive test failed:', error)
setTestResults(tests.map(test => ({
name: test.name,
status: 'error' as const,
error: error as string
})))
}
setIsRunning(false)
}
const clearResults = () => {
setTestResults([])
}
const getStatusIcon = (status: TestResult['status']) => {
switch (status) {
case 'pending':
return <div className="w-5 h-5 rounded-full bg-gray-300" />
case 'running':
return <Loader className="w-5 h-5 text-blue-500 animate-spin" />
case 'success':
return <CheckCircle className="w-5 h-5 text-green-500" />
case 'error':
return <XCircle className="w-5 h-5 text-red-500" />
}
}
const getStatusColor = (status: TestResult['status']) => {
switch (status) {
case 'pending':
return 'border-gray-200 bg-gray-50'
case 'running':
return 'border-blue-200 bg-blue-50'
case 'success':
return 'border-green-200 bg-green-50'
case 'error':
return 'border-red-200 bg-red-50'
}
}
const successCount = testResults.filter(r => r.status === 'success').length
const errorCount = testResults.filter(r => r.status === 'error').length
const totalTests = testResults.length
return (
<div className="min-h-screen bg-gray-50 p-6">
<div className="max-w-6xl mx-auto">
{/* 页面标题 */}
<div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900 mb-2">
Python Core
</h1>
<p className="text-gray-600">
Python Core的各项功能sidecar和模拟服务是否正常工作
</p>
</div>
{/* 控制按钮 */}
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6">
<div className="flex items-center gap-4 mb-4">
<button
onClick={runAllTests}
disabled={isRunning}
className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
<Play size={16} />
</button>
<button
onClick={runComprehensiveTest}
disabled={isRunning}
className="flex items-center gap-2 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
<RefreshCw size={16} />
</button>
<button
onClick={clearResults}
disabled={isRunning}
className="flex items-center gap-2 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
</button>
</div>
{/* 测试统计 */}
{totalTests > 0 && (
<div className="flex items-center gap-6 text-sm">
<span className="text-gray-600">
: {totalTests}
</span>
<span className="text-green-600">
: {successCount}
</span>
<span className="text-red-600">
: {errorCount}
</span>
<span className="text-gray-600">
: {totalTests > 0 ? Math.round((successCount / totalTests) * 100) : 0}%
</span>
</div>
)}
</div>
{/* 测试结果 */}
<div className="space-y-4">
{tests.map((test, index) => {
const result = testResults[index]
return (
<div
key={test.name}
className={`bg-white rounded-lg shadow-sm border-2 p-6 ${
result ? getStatusColor(result.status) : 'border-gray-200'
}`}
>
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
{result ? getStatusIcon(result.status) : getStatusIcon('pending')}
<div>
<h3 className="font-semibold text-gray-900">{test.name}</h3>
<p className="text-sm text-gray-600">{test.description}</p>
</div>
</div>
{result?.duration && (
<span className="text-xs text-gray-500">
{result.duration}ms
</span>
)}
</div>
{/* 测试结果详情 */}
{result && (
<div className="mt-4">
{result.status === 'success' && result.response && (
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
<div className="text-sm text-green-800 mb-2">
<strong>:</strong> {result.response.status ? '成功' : '失败'}
</div>
<div className="text-sm text-green-800 mb-2">
<strong>:</strong> {result.response.msg}
</div>
{result.response.data && (
<details className="text-sm text-green-800">
<summary className="cursor-pointer font-medium"></summary>
<pre className="mt-2 p-2 bg-green-100 rounded text-xs overflow-auto">
{JSON.stringify(result.response.data, null, 2)}
</pre>
</details>
)}
</div>
)}
{result.status === 'error' && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<div className="text-sm text-red-800">
<strong>:</strong> {result.error}
</div>
</div>
)}
</div>
)}
</div>
)
})}
</div>
</div>
</div>
)
}
export default PythonCoreTestPage