feat: restore VBA source code modules
All checks were successful
NTFY Notification / notify (push) Successful in 4s

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-02-04 11:07:36 +08:00
parent 25f6ae29ac
commit 58e84ddd25
7 changed files with 899 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
' ==============================================================================
' 模块: M99_TestRunner
' 职责: 单元测试,验证 M03_Logic 的核心算法
' 依赖: M03_Logic, clsErrorLogger (无需引用 Scripting Runtime)
' ==============================================================================
Option Explicit
Private m_Logger As clsErrorLogger
Private m_FailCount As Long
Private m_PassCount As Long
' ------------------------------------------------------------------------------
' 主入口: 运行所有测试
' ------------------------------------------------------------------------------
Public Sub RunAllTests()
' 初始化环境
Set m_Logger = New clsErrorLogger
M03_Logic.InitLogic m_Logger
m_FailCount = 0
m_PassCount = 0
Debug.Print String(50, "=")
Debug.Print "开始运行单元测试: " & Now
Debug.Print String(50, "-")
' 执行测试用例
Test_01_SimpleAtom
Test_02_SimpleAND
Test_03_SimpleOR
Test_04_CartesianProduct ' 核心:测试 (A OR B) AND C
Test_05_InequalityMerge ' 核心:测试 !=A AND !=B
Test_06_LogicConflict ' 核心:测试 A=1 AND A=2
Test_07_ComplexNested ' 核心:多层括号
' 汇总结果
Debug.Print String(50, "-")
If m_FailCount = 0 Then
Debug.Print "测试结果: ALL PASS! (共 " & m_PassCount & " 个测试点)"
Else
Debug.Print "测试结果: 失败 " & m_FailCount & " 个, 通过 " & m_PassCount & " 个"
End If
Debug.Print String(50, "=")
End Sub
' ------------------------------------------------------------------------------
' 测试用例 01: 简单赋值
' 输入: gclj=M20
' 期望: 1行数据, gclj字段为M20
' ------------------------------------------------------------------------------
Private Sub Test_01_SimpleAtom()
Dim col As Collection
Dim row As Object ' Dictionary
Set col = M03_Logic.ParseRule("gclj=M20", 1)
Assert_NotNull col, "T01_Col_Not_Null"
Assert_Equal col.count, 1, "T01_Count"
Set row = col(1)
Assert_Equal row("gclj"), "M20", "T01_Value_Check"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 02: AND 逻辑 (属性合并)
' 输入: gclj=M20 AND jycz=1
' 期望: 1行数据, 包含两个字段
' ------------------------------------------------------------------------------
Private Sub Test_02_SimpleAND()
Dim col As Collection
Dim row As Object
Set col = M03_Logic.ParseRule("gclj=M20 AND jycz=1", 2)
Assert_Equal col.count, 1, "T02_Count"
Set row = col(1)
Assert_Equal row("gclj"), "M20", "T02_Key1"
Assert_Equal row("jycz"), "1", "T02_Key2"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 03: OR 逻辑 (记录分裂)
' 输入: azxs=A0 OR azxs=A1
' 期望: 2行数据
' ------------------------------------------------------------------------------
Private Sub Test_03_SimpleOR()
Dim col As Collection
Set col = M03_Logic.ParseRule("azxs=A0 OR azxs=A1", 3)
Assert_Equal col.count, 2, "T03_Count"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 04: 笛卡尔积 (AND 连接 OR)
' 输入: gclj=M20 AND (azxs=A0 OR azxs=A1)
' 期望: 2行数据。行1(gclj=M20, azxs=A0), 行2(gclj=M20, azxs=A1)
' ------------------------------------------------------------------------------
Private Sub Test_04_CartesianProduct()
Dim col As Collection
Dim r1 As Object, r2 As Object
Set col = M03_Logic.ParseRule("gclj=M20 AND (azxs=A0 OR azxs=A1)", 4)
Assert_Equal col.count, 2, "T04_Count"
Set r1 = col(1)
Set r2 = col(2)
' 验证公共部分
Assert_Equal r1("gclj"), "M20", "T04_Row1_Common"
Assert_Equal r2("gclj"), "M20", "T04_Row2_Common"
' 验证差异部分
Dim hasA0 As Boolean, hasA1 As Boolean
If r1("azxs") = "A0" Or r2("azxs") = "A0" Then hasA0 = True
If r1("azxs") = "A1" Or r2("azxs") = "A1" Then hasA1 = True
Assert_Equal hasA0, True, "T04_Has_A0"
Assert_Equal hasA1, True, "T04_Has_A1"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 05: 不等于逻辑合并
' 输入: gclj!=M20 AND gclj!=M30
' 期望: 1行数据, gclj字段为 "!=M20,!=M30"
' ------------------------------------------------------------------------------
Private Sub Test_05_InequalityMerge()
Dim col As Collection
Dim row As Object
Set col = M03_Logic.ParseRule("gclj!=M20 AND gclj!=M30", 5)
Assert_Equal col.count, 1, "T05_Count"
Set row = col(1)
Assert_Equal row("gclj"), "!=M20,!=M30", "T05_Value_Merge"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 06: 逻辑冲突检测 (修正版)
' 输入: gclj=M20 AND gclj=M30
' 期望: 返回 Nothing 或 空集合,且 Logger 中有记录
' ------------------------------------------------------------------------------
Private Sub Test_06_LogicConflict()
Dim col As Collection
' 重置 Logger
Set m_Logger = New clsErrorLogger
M03_Logic.InitLogic m_Logger
' 此时 ParseRule 内部会捕捉冲突
Set col = M03_Logic.ParseRule("gclj=M20 AND gclj=M30", 6)
' 检查结果: 应该是 Nothing 或者 Count=0
Dim isInvalid As Boolean
If col Is Nothing Then
isInvalid = True
Else
If col.count = 0 Then isInvalid = True Else isInvalid = False
End If
Assert_Equal isInvalid, True, "T06_Should_Return_Empty_Or_Nothing"
Assert_Equal m_Logger.HasErrors, True, "T06_Should_Log_Error"
End Sub
' ------------------------------------------------------------------------------
' 测试用例 07: 复杂嵌套
' 输入: A=1 AND (B=1 OR (B=2 AND C=3))
' 期望: 2行
' Row 1: A=1, B=1
' Row 2: A=1, B=2, C=3
' ------------------------------------------------------------------------------
Private Sub Test_07_ComplexNested()
Dim col As Collection
Set col = M03_Logic.ParseRule("A=1 AND (B=1 OR (B=2 AND C=3))", 7)
Assert_Equal col.count, 2, "T07_Count"
Dim count2 As Long, count3 As Long
Dim i As Long
Dim r As Object
For i = 1 To col.count
Set r = col(i)
If r.count = 2 Then count2 = count2 + 1
If r.count = 3 Then count3 = count3 + 1
Next i
Assert_Equal count2, 1, "T07_Row_With_2_Keys"
Assert_Equal count3, 1, "T07_Row_With_3_Keys"
End Sub
' ==============================================================================
' 辅助断言函数
' ==============================================================================
Private Sub Assert_Equal(actual As Variant, expected As Variant, testName As String)
If CStr(actual) = CStr(expected) Then
' Debug.Print " [PASS] " & testName
m_PassCount = m_PassCount + 1
Else
Debug.Print " [FAIL] " & testName & " | Expected: " & expected & ", Actual: " & actual
m_FailCount = m_FailCount + 1
End If
End Sub
Private Sub Assert_NotNull(obj As Object, testName As String)
If Not obj Is Nothing Then
m_PassCount = m_PassCount + 1
Else
Debug.Print " [FAIL] " & testName & " | Object is Nothing"
m_FailCount = m_FailCount + 1
End If
End Sub