تغطية الاختبارات

يتم حماية ForgeIEC من خلال مجموعة اختبارات آلية شاملة. يتم التحقق من كل commit قبل الدمج مقابل 117 اختبار وحدة تغطي مفردات IEC 61131-3 Structured Text الكاملة وجميع الكتل الوظيفية القياسية ونظام المهام المتعددة.

نظرة عامة على مجموعات الاختبار

المجموعةالاختباراتيتحقق من
FStCompilerTest101مفردات ST الكاملة
FStLibraryTest8جميع الكتل القياسية الـ 132 (FBs + FCs)
FCodeGeneratorThreadingTest8جدولة المهام المتعددة + المزامنة بدون أقفال
الإجمالي1170 أخطاء

1. مفردات ST (FStCompilerTest)

101 اختبار يتحقق من كل بنية لغوية مدعومة في IEC 61131-3 Structured Text. كل اختبار يجمّع جزءًا من كود ST عبر FStCompiler ويتحقق من كود C++ المُولَّد.

1.1 التعيينات

الاختباركود STيتحقق من
assignSimplea := 42;تعيين بسيط
assignExpressiona := b + 1;تعيين بتعبير
assignExternalExtVar := 10;وصول VAR_EXTERNAL
assignGvlQualifiedGVL.ExtVar := 5;مسار GVL مؤهل

1.2 العوامل الحسابية

الاختباركود STعامل C
arithmeticAdda := b + 1;+
arithmeticSuba := b - 1;-
arithmeticMula := b * 2;*
arithmeticDiva := b / 2;/
arithmeticModa := b MOD 3;%
arithmeticPowerc := x ** 2.0;EXPT()
arithmeticNegatea := -b;-(...)
arithmeticParenthesesa := (b + 1) * 2;الأقواس

1.3 عوامل المقارنة

الاختباركود STعامل C
compareEqualflag := a = b;==
compareNotEqualflag := a <> b;!=
compareLessflag := a < b;<
compareGreaterflag := a > b;>
compareLessEqualflag := a <= b;<=
compareGreaterEqualflag := a >= b;>=

1.4 العوامل المنطقية

الاختباركود STعامل C
boolAndflag := flag AND flag;&&
boolOrflag := flag OR flag;||
boolXorflag := flag XOR flag;^
boolNotflag := NOT flag;!

1.5 القيم الحرفية

الاختباركود STيتحقق من
literalIntegera := 12345;عدد صحيح
literalRealc := 3.14;فاصلة عائمة
literalBoolTrueflag := TRUE;قيمة منطقية
literalBoolFalseflag := FALSE;قيمة منطقية
literalStringtext := 'hello';سلسلة نصية
literalTimecounter := T#500ms;ثابت زمني

1.6 هياكل التحكم

IF / ELSIF / ELSE / END_IF

الاختباريتحقق من
ifSimpleشرط بسيط
ifElseتفرع If-Else
ifElsifتفرع متعدد مع ELSIF
ifNestedكتل IF متداخلة

FOR / WHILE / REPEAT

الاختباريتحقق من
forSimpleFOR idx := 0 TO 10 DO
forWithByFOR مع خطوة BY
whileLoopحلقة WHILE
repeatUntilحلقة REPEAT/UNTIL

CASE

الاختباريتحقق من
caseStatementCASE/OF مع عدة تسميات + switch/case/break

RETURN / EXIT

الاختباريتحقق من
returnStatementRETURN → goto __end
exitStatementEXIT داخل FOR → break

1.7 الكتل الوظيفية (استدعاءات FB)

الاختباريتحقق من
fbCallWithInputsMyTon(IN := flag, PT := T#500ms);
fbCallWithOutputAssignMyTimer(IN := flag, Q => flag); — تعيين OUT =>

1.8 الوصول إلى المصفوفات

الاختباريتحقق من
arrayReadSubscripta := arr[3];
arrayWriteSubscriptarr[5] := 42;
arrayComputedIndexa := arr[idx + 1];
arrayInForLoopوصول مصفوفة في حلقة FOR

1.9 تحويلات الأنواع

يتعرف المترجم على نمط XXX_TO_YYY ويولّد تحويلات بأسلوب C ((TYPE)value)، وفقًا لمعيار IEC.

الاختباركود STيولّد
typeConvIntToRealINT_TO_REAL(a)(REAL)a
convRealToIntREAL_TO_INT(c)(INT)c
convBoolToIntBOOL_TO_INT(flag)(INT)flag
convIntToBoolINT_TO_BOOL(a)(BOOL)a
convDintToRealDINT_TO_REAL(counter)(REAL)counter
convIntToDintINT_TO_DINT(a)(DINT)a

1.10 الوصول إلى أعضاء الهيكل

الاختباريتحقق من
structMemberAccesspos.x := 42;data__->pos.value.x

1.11 متغيرات عبر المهام (متعددة المهام)

الاختباريتحقق من
crossPrimitiveGet__GET_EXTERNAL_ATOMIC للقراءة بدون أقفال
crossPrimitiveSet__SET_EXTERNAL_ATOMIC للكتابة بدون أقفال
crossStructuredGet__snap_ وصول لقطة محلية للخيط
crossStructuredMemberAccess__snap_Struct.field وصول

1.12 الكتل الوظيفية القياسية

يتم إنشاء نسخة من كل FB قياسي واستدعاؤها:

الاختبارنوع FBيتحقق من
fbTonTONتأخير التشغيل
fbTofTOFتأخير الإيقاف
fbTpTPمؤقت نبضي
fbCtuCTUعداد تصاعدي
fbCtdCTDعداد تنازلي
fbRtrigR_TRIGحافة صاعدة
fbFtrigF_TRIGحافة هابطة
fbRsRSإعادة تعيين مهيمنة
fbSrSRضبط مهيمن

1.13 الدوال القياسية

الفئةالاختباراتالدوال
الرياضيات12ABS, SQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, EXP, LN, LOG, TRUNC
الاختيار4SEL, LIMIT, MIN, MAX
السلاسل النصية6LEN, LEFT, RIGHT, MID, CONCAT, FIND
إزاحة البتات4SHL, SHR, ROL, ROR
تحويل الأنواع6INT_TO_REAL, REAL_TO_INT, BOOL_TO_INT, …

1.14 الحالات الحدية

الاختباريتحقق من
complexNestedExpressionتعبيرات متداخلة
multipleStatementsOnSeparateLinesبرامج متعددة الأسطر
emptyBodyجسم POU فارغ
commentOnlyBodyتعليقات فقط
caseInsensitiveKeywordsIF/if/If
caseInsensitiveVariablesحساسية الأحرف الكبيرة/الصغيرة

2. المكتبة القياسية (FStLibraryTest)

8 اختبارات مبنية على البيانات تتحقق من جميع الكتل الـ 132 في المكتبة القياسية (standard_library.sql) تلقائيًا.

2.1 الكتل الوظيفية (13 FB)

الاختباريتحقق من
fbSingleInstanceكل FB قابل للإنشاء والاستدعاء بشكل فردي
fbDoubleInstanceنسختان من نفس نوع FB في وقت واحد
fbOutputReadجميع المخرجات قابلة للقراءة بعد الاستدعاء

الكتل الوظيفية المغطاة: SR, RS, R_TRIG, F_TRIG, CTU, CTD, CTUD, TON, TOF, TP, RTC, SEMA, RampGen

2.2 الدوال (119 FC)

الاختباريتحقق من
fcCallكل FC قابلة للاستدعاء مع المعاملات الصحيحة (104 تم اختبارها)
fcInExpressionقيمة إرجاع FC قابلة للاستخدام في التعبيرات

الفئات المغطاة:

  • الحساب: ADD, SUB, MUL, DIV, MOD, EXPT, ABS
  • المقارنة: EQ, NE, LT, GT, LE, GE
  • حساب المثلثات: SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2
  • اللوغاريتمات: EXP, LN, LOG, SQRT
  • الاختيار: SEL, MUX, LIMIT, MIN, MAX, MOVE, CLAMP
  • السلاسل النصية: LEN, LEFT, RIGHT, MID, CONCAT, INSERT, DELETE, REPLACE, FIND
  • إزاحة البتات: SHL, SHR, ROL, ROR
  • تحويل الأنواع: 60+ دالة تحويل (BOOL_TO_INT, INT_TO_REAL, …)
  • إضافات ForgeIEC: LERP, MAP_RANGE, HYPOT, DEG, RAD, IK_2Link, CABS, CADD, CMUL, CSUB, CARG, CCONJ, CPOLAR, CRECT

3. المهام المتعددة (FCodeGeneratorThreadingTest)

8 اختبارات تتحقق من نظام جدولة المهام المتعددة الكامل وفقًا لمواصفات التصميم (MT-spec, docs/design/multi-task-scheduler.md).

الاختباريتحقق من
singleProgramDefaultTaskبرنامج واحد بدون مهمة صريحة → تركيب DefaultTask، بدون خيوط
twoProgramsTwoTasksمهمتان → RESOURCE0_start__، Legacy-Shim config_run__، كلا خيطي المهمة
crossPrimitiveAtomicEmissionمتغير INT مشترك → تخزين Location بـ std::atomic<>، __GET_EXTERNAL_ATOMIC في الجسم
crossStructuredDoubleBufferSTRUCT مشترك → __DBUF_[2] + thread_local __snap_ + نسخ Double-Buffer دخول/خروج
localVarNoSyncمتغير في مهمة واحدة فقط → __SET_EXTERNAL عادي، بدون Atomic
conflictTwoWritersمهمتان تكتبان نفس المتغير → تحذير ترجمة
singleProgramDefaultTaskالتوافق مع الإصدارات السابقة: المشاريع الحالية تعمل بدون تغيير

بنية المهام المتعددة

Primary Task (Task 0)          Secondary Tasks (1..N)
    |                               |
    | config_run__()                | RESOURCE0_task_thread__()
    |   ├─ sync_in                  |   ├─ dbuf_rd (copy-in)
    |   ├─ TASK0_body__()           |   ├─ TASKn_body__()
    |   └─ sync_out                 |   └─ dbuf_wr (copy-out)
    |                               |
    | [تحت bufferLock]              | [lock-free]

آليات المزامنة:

  • CrossPrimitive (BOOL, INT, REAL, …): std::atomic<T> على متغير الموقع، __GET_EXTERNAL_ATOMIC / __SET_EXTERNAL_ATOMIC في كود الجسم
  • CrossStructured (STRUCT, ARRAY, STRING): Double-Buffer __DBUF_[2] مع مؤشر كتابة ذري، لقطات thread_local __snap_ لاتساق المجموعة

ضمان الجودة

التحقق الآلي

تُنفَّذ الاختبارات مع كل بناء باستخدام -DBUILD_TESTS=ON. التكامل مع خط أنابيب CI (Forgejo Actions) جاهز.

الاختبارات المبنية على البيانات

تقرأ اختبارات المكتبة (FStLibraryTest) تعريفات الكتل مباشرة من standard_library.sql. عند إضافة كتل جديدة، يتم اختبارها تلقائيًا — لا حاجة لإنشاء حالات اختبار يدويًا.

الاكتمال

تغطي مجموعة الاختبارات مفردات IEC 61131-3 Structured Text الكاملة كما يدعمها ForgeIEC:

  • جميع العوامل (حسابية، مقارنة، منطقية، إزاحة بتات)
  • جميع هياكل التحكم (IF, FOR, WHILE, REPEAT, CASE)
  • جميع أنواع القيم الحرفية (Integer, Real, Bool, String, Time)
  • جميع الكتل الوظيفية والدوال القياسية (132 كتلة)
  • الوصول إلى المصفوفات والهياكل
  • متغيرات GVL المؤهلة
  • المزامنة عبر المهام (Atomics + Double-Buffer)
  • تحويلات الأنواع (توليد تحويلات C)