Errors and testing
Error handling#
فابر تفصل ثلاثة أفكار مترابطة تدمجها لغات كثيرة في شكل واحد:
| Construct | المعنى |
|---|---|
→ T | قناة عودة النجاح المعتادة |
T ∪ nihil | غياب في نطاق قيمة النجاح |
⇥ E | قناة خروج بديلة قابلة للاسترداد للأخطاء |
عودة طبيعية#
دالة porta(عدد x) → عدد {
إذا x ≺ 0 إذن أعد 0
أعد x * 2
}دوال قابلة للفشل#
استخدم ⇥ حين يمكن لدالة أن تخرج عبر قناة خطأ:
دالة divide(عدد a, عدد b) → عدد ⇥ نص {
إذا b ≡ 0 {
ارم "division by zero"
}
أعد a / b
}رمي — iace#
iace ترسل قيمة على قناة الخطأ:
دالة exigePositivum(عدد value) → فراغ ⇥ نص {
إذا value ≺ 0 {
ارم "negative value"
}
}استرداد — fac / cape#
يسترد المستدعون محليًا بكتلة افعل ومعالج التقط:
دالة divide(عدد a, عدد b) → عدد {
إذا b ≡ 0 إذن أعد 0
أعد a / b
}
دالة tutum(عدد a, عدد b) → عدد {
افعل {
أعد divide(a, b)
}
التقط err {
نبه err
أعد 0
}
}لا يُعد الاستدعاء المباشر القابل للفشل تعبيرًا عاديًا. ضع استدعاءات
الدوال من النمط → T ⇥ E داخل حدود افعل / التقط نشطة.
استرداد تحويل مضمن#
يمكن لـ ⇥ أيضًا تحديد قيمة استرداد مضمنة على تحويلات ↦:
ثابت نص raw ← "42"
ثابت عدد n ← raw ↦ عدد ⇥ 0تأثير قابل للفشل فقط#
للدوال التي تخطئ لكن لا تعيد قيمة نجاح، احذف → T:
دالة exigePositivum(عدد value) → فراغ ⇥ نص {
إذا value ≺ 0 {
ارم "negative value"
}
}الحالة الراهنة#
→ و أعد و ⇥ و iace و افعل / التقط هي أسطح نحوية ومدققة
حية. خفض Rust و Go لسلوك ⇥ / iace / التقط الكامل وقت التشغيل لا
يزال فجوة خلفية — فهذه تجتاز فحص النمط لكنها لا تصدر بعد شيفرة وقت تشغيل
قابلة للفشل إلى كل الأهداف.
Inline testing#
تمتلك Faber إطار عمل اختبارات من الدرجة الأولى مدمجًا في اللغة بثلاث كلمات
مفتاحية: probandum تُعلن عن مجموعة اختبارات، وproba تُعلن عن حالة اختبار
مفردة، وadfirma تؤكد صحة شرط. تعيش الاختبارات في نفس الملف مع الشيفرة التي
تختبرها، وتُشغَّل عبر faber test، وتدعم نفس خط أنابيب التصريف الخاص بشيفرة
الإنتاج — واعية بالإعدادات المحلية، مدققة الأنواع، ومتعددة الأهداف.
الكلمات المفتاحية الثلاث#
| الكلمة المفتاحية | الدور | المكافئ التقريبي |
|---|---|---|
probandum | تُعلن عن مجموعة اختبارات مسماة | describe، #[cfg(test)] mod |
proba | تُعلن عن حالة اختبار مفردة | it، #[test] |
adfirma | تؤكد صحة شرط أثناء التنفيذ | assert!، assert_eq! |
probandum — مجموعة الاختبارات#
تجمّع كتلة probandum حالات الاختبار المرتبطة ببعضها. يمكن تداخل المجموعات
لتنظيم الاختبارات بشكل هرمي:
اختبر "unum plus unum" {
أكد 1 + 1 ≡ 2
}
اختبر "multiplicatio" {
أكد 3 * 4 ≡ 12
}
اختبر "comparatio" {
ثابت عدد x ← 10
أكد x ≥ 10
}proba — حالة الاختبار#
تحتوي كتلة proba على منطق الاختبار. يمكنها استخدام أي شيفرة Faber —
ارتباطات المتغيرات، استدعاءات الدوال، تدفق التحكم — وتنتهي بتأكيد adfirma
واحد أو أكثر. يمكن وسم الاختبارات بعلامة tag اختيارية للتنفيذ الانتقائي:
proba "echo formats operands with one space" tag "coreutils" {
adfirma echo_textus(["hello", "world"]) ≡ "hello world"
}adfirma — التأكيد#
تقيّم adfirma تعبيرًا منطقيًا وتُبلغ عن الفشل إذا كان خاطئًا. توفر رسالة
نصية اختيارية سياقًا عند الفشل:
بداية {
ثابت عدد x ← 10
# Simple assertion
أكد x ≻ 0
# With custom message
أكد x ≡ 10 secus "x decem esse debet"
# Multiple assertions in sequence
ثابت نص nomen ← "Marcus"
أكد nomen ≡ "Marcus"
أكد nomen ≠ "" secus "nomen vacuum non sit"
}سير العمل#
تُشغَّل الاختبارات عبر الأمر faber test:
faber test # run all tests in the current package
faber test examples/coreutils/packages/echo # run tests for a specific packageلأن الاختبارات تعيش جنبًا إلى جنب مع المصدر في نفس ملف .fab، فلا يوجد هيكل
مجلدات منفصل للاختبارات، ولا إعلان لوحدة اختبارات، ولا تمييز في سكربت البناء
بين بنائي الاختبار والإنتاج. يعرف المصرف أي الكتل هي شيفرة اختبار وأيها شيفرة
إنتاج من خلال الكلمات المفتاحية المستخدمة — تُحلَّل probandum وproba لكنها
تُستبعد من بنائي الإنتاج.
مثال من العالم الحقيقي#
توضح حزمة echo في coreutils إطار عمل الاختبارات عمليًا. تعيش الاختبارات في
نفس ملف التنفيذ، وتغطي تحليل الخيارات، توسيع الرموز الخاصة، والحالات الحدية:
probandum "echo formatting" tag "coreutils" {
proba "empty operands format as empty text" {
fixum lista<textus> words ← vacua
adfirma echo_textus(words) ≡ ""
}
proba "single operand is unchanged" {
adfirma echo_textus(["hello"]) ≡ "hello"
}
proba "-E is a leading no-op option" {
adfirma echo_textus(["-E", "hello", "world"]) ≡ "hello world"
}
proba "-n suppresses the trailing newline flag" {
adfirma echo_novam_lineam(["-n", "hello"]) ≡ falsum
}
proba "-e expands the declared escape subset" {
adfirma echo_textus(["-e", "a\\nb"]) ≡ "a\nb"
adfirma echo_textus(["-e", "a\\tb"]) ≡ "a\tb"
}
}ملاحظات التصميم#
تميز عدة خيارات تصميمية إطار اختبارات Faber عن النهج التقليدية:
- لا يوجد ثنائي اختبار منفصل. الاختبارات هي تصريحات في نفس ملف المصدر، وليست هدف تصريف منفصل. يصفي المصرف كتل الاختبار من مخرجات الإنتاج.
- الوسوم، وليس المجلدات. تُنظم الاختبارات بعلامات
tagبدلًا من هيكل المجلدات. يمكن للاختبار الانتماء إلى عدة محاور تنظيمية دون نقله. - خط أنابيب تصريف كامل. الاختبارات مدققة الأنواع، محللة، وواعية بالإعدادات المحلية — نفس علم
--reader-localeينطبق على مخرجات الاختبار. - متعدد الأهداف. تشغّل الاختبارات عبر أي خلفية يستهدفها الرزمة — مُنفّذ MIR لـ
faber test --interpret، وRust مصرف لـfaber test. - مجموعات متداخلة. يمكن تداخل كتل
probandum، معكسةً هيكل الشيفرة التي تختبرها.
المراجع#
examples/corpus/probandum/— ملفات probandum النموذجيةexamples/corpus/proba/— ملفات proba النموذجيةexamples/corpus/adfirma/— ملفات adfirma النموذجيةexamples/coreutils/packages/echo/src/main.fab— استخدام واقعي مع الوسوم