Spaces:
Build error
Build error
File size: 10,286 Bytes
9db7e09 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | """
🧪 تست کامل ماژولهای ناشناسسازی
Complete testing suite for all modules
"""
import sys
import os
# اضافه کردن مسیر پروژه به Python path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from modules import (
count_tokens,
should_use_chunking,
TextChunker,
EntityNormalizer,
EntityMerger
)
def test_utils():
"""تست توابع کمکی"""
print("=" * 60)
print("🧪 Test 1: Utils Module")
print("=" * 60)
# Token counting
text = "این یک متن تست است برای شمارش توکنها."
tokens = count_tokens(text)
print(f"\n✅ Token Counting:")
print(f" Text: {text}")
print(f" Tokens: {tokens}")
assert tokens > 0, "Token count should be positive"
# Chunking decision
short_text = "متن کوتاه"
long_text = "متن بلند " * 2000
print(f"\n✅ Chunking Decision:")
short_decision = should_use_chunking(short_text, threshold=1000)
long_decision = should_use_chunking(long_text, threshold=1000)
print(f" Short text: {short_decision} (expected: False)")
print(f" Long text: {long_decision} (expected: True)")
assert short_decision == False, "Short text should not need chunking"
assert long_decision == True, "Long text should need chunking"
print("\n✅ Utils tests passed!")
def test_normalizer():
"""تست نرمالسازی"""
print("\n" + "=" * 60)
print("🧪 Test 2: Normalizer Module")
print("=" * 60)
normalizer = EntityNormalizer()
# Person
print("\n✅ Person Normalization:")
test_cases = [
("آقای علی احمدی", "علی احمدی"),
("دکتر مریم کریمی", "مریم کریمی"),
]
for original, expected in test_cases:
result = normalizer.normalize_person(original)
print(f" '{original}' → '{result}'")
assert result == expected, f"Expected '{expected}', got '{result}'"
# Company
print("\n✅ Company Normalization:")
company_result = normalizer.normalize_company("شرکت ملی نفت ایران")
print(f" 'شرکت ملی نفت ایران' → '{company_result}'")
assert "شرکت ملی نفت" in company_result
# Amount
print("\n✅ Amount Normalization:")
amount_result = normalizer.normalize_amount("۵۰ میلیارد ریال")
print(f" '۵۰ میلیارد ریال' → '{amount_result}'")
assert "50" in amount_result and "میلیارد" in amount_result
# Percent
print("\n✅ Percent Normalization:")
percent_result = normalizer.normalize_percent("۱۵٪")
print(f" '۱۵٪' → '{percent_result}'")
assert "15" in percent_result and "درصد" in percent_result
print("\n✅ Normalizer tests passed!")
def test_chunker():
"""تست chunking"""
print("\n" + "=" * 60)
print("🧪 Test 3: Chunker Module")
print("=" * 60)
# متن تست
test_text = """
شرکت پارس در سال گذشته فروش 50 میلیارد ریال داشت. این رقم رشد 15 درصدی نشان میدهد.
علی احمدی مدیرعامل شرکت است. شرکت صبا نیز در همین بازار فعالیت میکند.
شرکت صبا فروش 30 میلیارد ریال داشت. مریم کریمی مدیر مالی است.
همکاری بین دو شرکت در دستور کار است. قرارداد 20 میلیارد ریالی است.
سرمایهگذاری 10 میلیارد ریال انجام میشود. بازده 25 درصد پیشبینی شده است.
"""
chunker = TextChunker(chunk_size=100, overlap=20)
chunks = chunker.create_chunks(test_text)
print(f"\n✅ Chunking Results:")
print(f" Original text: {len(test_text)} chars")
print(f" Number of chunks: {len(chunks)}")
for chunk in chunks:
print(f"\n {chunk['chunk_id']}:")
print(f" Tokens: {chunk['tokens']}")
print(f" Length: {chunk['length']} chars")
print(f" Preview: {chunk['text'][:60]}...")
assert len(chunks) > 0, "Should create at least one chunk"
assert chunker.validate_chunks(chunks), "Chunks should be valid"
print("\n✅ Chunker tests passed!")
def test_merger():
"""تست merge"""
print("\n" + "=" * 60)
print("🧪 Test 4: Merger Module")
print("=" * 60)
merger = EntityMerger(fuzzy_threshold=0.75)
# شبیهسازی دو mapping table
table1 = {
"chunk_id": "chunk_01",
"mapping": {
"company-01": "شرکت پارس",
"company-02": "شرکت صبا",
"person-01": "علی احمدی",
"person-02": "مریم کریمی",
"amount-01": "50 میلیارد ریال",
"amount-02": "30 میلیارد ریال",
"percent-01": "15 درصد"
}
}
table2 = {
"chunk_id": "chunk_02",
"mapping": {
"company-01": "شرکت پارس", # فاصله اضافی - باید match بشه
"company-02": "شرکت ملی نفت", # جدید
"person-01": "علی احمدی", # باید match بشه
"person-02": "رضا محمدی", # جدید
"amount-01": "100 میلیارد ریال", # جدید
"percent-01": "40 درصد" # جدید
}
}
result = merger.merge_mappings([table1, table2])
print(f"\n✅ Merge Results:")
print(f"\nGlobal Mapping ({len(result['global_mapping'])} entities):")
for placeholder, value in sorted(result['global_mapping'].items()):
print(f" {placeholder}: {value}")
print(f"\nRemapping for chunk_02:")
remap = result['remapping'][1]['mapping']
for old, new in remap.items():
print(f" {old} → {new}")
# بررسیها
assert len(result['global_mapping']) > len(table1['mapping']), \
"Global mapping should have more entities"
assert len(result['remapping']) == 2, \
"Should have remapping for 2 chunks"
# بررسی exact match
assert "company-01" in remap and remap["company-01"] == "company-01", \
"شرکت پارس should match exactly"
assert "person-01" in remap and remap["person-01"] == "person-01", \
"علی احمدی should match exactly"
print("\n✅ Merger tests passed!")
def test_end_to_end():
"""تست end-to-end کامل"""
print("\n" + "=" * 60)
print("🧪 Test 5: End-to-End Integration")
print("=" * 60)
# متن بلند برای تست
long_text = """
شرکت پارس در سال 1402 عملکرد بسیار خوبی داشت. فروش این شرکت به 50 میلیارد ریال رسید.
علی احمدی، مدیرعامل شرکت پارس، اعلام کرد که این رشد 15 درصدی قابل توجه است.
شرکت صبا نیز در همین صنعت فعالیت میکند. فروش شرکت صبا 30 میلیارد ریال بود.
مریم کریمی، مدیر مالی شرکت صبا، پیشبینی کرد که در سال آینده به 40 میلیارد خواهد رسید.
همکاری بین شرکت پارس و شرکت صبا در دستور کار قرار دارد. قرارداد به ارزش 20 میلیارد ریال
در حال نهایی شدن است. علی احمدی و مریم کریمی در مذاکرات شرکت دارند.
"""
# 1. تصمیمگیری
use_chunking = should_use_chunking(long_text, threshold=50)
print(f"\n📊 Use chunking: {use_chunking}")
if use_chunking:
# 2. Chunking
chunker = TextChunker(chunk_size=100, overlap=20)
chunks = chunker.create_chunks(long_text)
print(f"✅ Created {len(chunks)} chunks")
# 3. شبیهسازی ناشناسسازی (بدون Cerebras)
# فرض: هر chunk یک mapping دارد
mapping_tables = []
for chunk in chunks:
# شبیهسازی mapping
mapping_tables.append({
"chunk_id": chunk['chunk_id'],
"mapping": {
"company-01": "شرکت پارس",
"person-01": "علی احمدی",
"amount-01": f"مبلغ تست {chunk['chunk_id']}"
}
})
# 4. Merge
merger = EntityMerger()
merge_result = merger.merge_mappings(mapping_tables)
print(f"✅ Merged to {len(merge_result['global_mapping'])} global entities")
# 5. بررسی consistency
# باید "شرکت پارس" و "علی احمدی" در همه chunks یکسان باشند
for i, remap_data in enumerate(merge_result['remapping'][1:], start=2):
remap = remap_data['mapping']
if "company-01" in remap:
assert remap["company-01"] == "company-01", \
f"company-01 in chunk {i} should map to global company-01"
print("✅ Consistency check passed!")
print("\n✅ End-to-end test passed!")
def run_all_tests():
"""اجرای تمام تستها"""
print("\n" + "🚀" * 30)
print("Starting Complete Test Suite")
print("🚀" * 30 + "\n")
try:
test_utils()
test_normalizer()
test_chunker()
test_merger()
test_end_to_end()
print("\n" + "=" * 60)
print("✅✅✅ ALL TESTS PASSED! ✅✅✅")
print("=" * 60)
return True
except AssertionError as e:
print("\n" + "=" * 60)
print(f"❌ TEST FAILED: {e}")
print("=" * 60)
return False
except Exception as e:
print("\n" + "=" * 60)
print(f"❌ ERROR: {e}")
import traceback
traceback.print_exc()
print("=" * 60)
return False
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)
|