Каков наилучший способ реализации assertions с использованием Progress 4GL или WebSpeed?Выполнение утверждений 4GL
ответ
После некоторого рассмотрения здесь мое решение к проблеме. Она работает на основе предположения, что среда разработки PROPATH отличается от тестирования и производственной среды и кода всегда перекомпилирована для тестирования или производственного назначения:
&IF PROPATH MATCHES '*development*' &THEN
&SCOPED-DEFINE ASSERTION {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}
IF NOT ({&ASSERTION}) THEN
MESSAGE "Failed assertion {&ASSERTION} in" PROGRAM-NAME(1).
IF ({&ASSERTION}) = ? THEN
MESSAGE "Unknown value as a result of assertion {&ASSERTION} in"
PROGRAM-NAME(1).
&ENDIF
Код предназначен, чтобы избежать каких-либо побочных эффектов и работает одинаково хорошо в любой среде исполнения (GUI или ChUI, WebSpeed, AppServer, пакет и т. д.).
1) Сохраните код как файл с именем "assert" (без какого-либо расширения).
2) Поместите файл в каталог, на который указывает PROPATH.
использование 3) Пример:
{assert valid-handle(hProc)}
{assert i > 0 and i <= 100}
{assert cExtra begins ‘opt’} /* note the single quotes */
{assert dtEnd > = dtStart}
Как вариант это можно не полагаться на PROPATH вообще, имея всего лишь пустой включаемый файл в тестовой и производственной среде, разрабатываемая версия будет просто:
&SCOPED-DEFINE ASSERTION {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}
IF NOT ({&ASSERTION}) THEN
MESSAGE "Failed assertion {&ASSERTION} in" PROGRAM-NAME(1).
IF ({&ASSERTION}) = ? THEN
MESSAGE "Unknown value as a result of assertion {&ASSERTION} in"
PROGRAM-NAME(1).
Дополнительный совет - добавить автоматический текстовый макрос к своему выбору, который автоматически расширится на {assert}.
Поскольку прогресс не имеет встроенную обработку для утверждений, но лучше я придумал это:
IF NOT <assertion> THEN
RUN assertionFailed.p.
assertionFailed.p может отправить программист или войти условия, а также выйти из грациозно.
Учитывая, что утверждения, как правило, исключаются из окончательного кода, я бы предложил маршрут препроцессора. Вы можете сделать что-то вроде следующего, чтобы установить его как два файла include. Когда вы компилируете его для производства, убедитесь, что debugalert.i пуст. assert.i может быть отредактирован, чтобы сделать все, что вам нравится сообщение, остановка, электронная почта и т.д. ...
Для установки утверждения вы просто следовать формат {assert.i & состояния =}
/* assert.i */ {debugalert.i}
& IF DEFINED (DEBUGALERT) <> 0 & ТОГДА
ЕСЛИ НЕ {& СО NDITION} THEN DO:
MESSAGE THIS-PROCEDURE:FILENAME "ERROR...{&CONDITION}"
VIEW-AS ALERT-BOX.
/* add code to email message etc.. or stop */
END.
& ENDIF
/* debugalert.i на тест или среду разработки отключить утверждения удалить это утверждение */
& GLOBAL-DEFINE DEBUGALERT
/* В вашем тестовом коде вы просто выполните следующее: / / тестирования утверждение */
DEF VAR h_ct AS INT NO-UNDO INIT 10.
{assert.i & СОСТОЯНИИ = "h_ct = 8"}