Errors and testing
Error handling#
Faber तीन संबंधित विचारों को अलग रखता है, जिन्हें कई भाषाएँ एक ही रूप में मिला देती हैं:
| निर्माण | अर्थ |
|---|---|
→ 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, और करो / पकड़ो लाइव व्याकरण और चेकर
सतहें हैं। पूर्ण ⇥ / iace / पकड़ो रनटाइम व्यवहार के लिए Rust और Go
लोअरिंग में अभी बैकएंड की कमी है — ये टाइप-चेकिंग पास करते हैं, लेकिन
अभी सभी लक्ष्यों के लिए विफल हो सकने वाला रनटाइम कोड उत्पन्न नहीं करते।
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 को पार्स किया जाता है, लेकिन प्रोडक्शन बिल्ड से बाहर रखा जाता है।
वास्तविक उदाहरण#
coreutils का echo पैकेज परीक्षण फ्रेमवर्क को व्यवहार में प्रदर्शित करता है। परीक्षण उसी फ़ाइल में इम्प्लीमेंटेशन के साथ रहते हैं और विकल्प पार्सिंग, एस्केप विस्तार तथा किनारी स्थितियों को कवर करते हैं:
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फ़्लैग लागू होता है। - बहु-लक्ष्य। परीक्षण पैकेज द्वारा लक्षित बैकएंड के माध्यम से चलते हैं —
faber test --interpretके लिए MIR स्टेपर औरfaber testके लिए कंपाइल्ड Rust। - नेस्टेड सूट।
probandumब्लॉक नेस्ट किए जा सकते हैं और उस कोड की संरचना को प्रतिबिंबित करते हैं जिसका वे परीक्षण करते हैं।
संदर्भ#
examples/corpus/probandum/— probandum उदाहरण फ़ाइलेंexamples/corpus/proba/— proba उदाहरण फ़ाइलेंexamples/corpus/adfirma/— adfirma उदाहरण फ़ाइलेंexamples/coreutils/packages/echo/src/main.fab— टैग के साथ वास्तविक उपयोग