Update to provide coverage analysis for Cache

The files were updated to provide coverage analysis for Intersystems
Cache systems as well as GT.M.
This commit is contained in:
JOEL IVEY 2015-12-13 15:43:49 -08:00
parent 22c042f8a1
commit 68683ac779
20 changed files with 7915 additions and 4139 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
%ut ;VEN-SMH/JLI - PRIMARY PROGRAM FOR M-UNIT TESTING ;09/14/15 09:38
%ut ;VEN-SMH/JLI - PRIMARY PROGRAM FOR M-UNIT TESTING ;12/07/15 15:32
;;0.2;MASH UTILITIES;;;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Joel L. Ivey as XTMUNIT while working for U.S. Department of Veterans Affairs 2003-2012
@ -145,13 +145,44 @@ VERBOSE1(%utETRY,%utI) ; Print out the entry point info
Q
;
CHKTF(XTSTVAL,XTERMSG) ; Entry point for checking True or False values
; ZEXCEPT: %utERRL,%utGUI - CREATED IN SETUP, KILLED IN END
; ZEXCEPT: %ut - NEWED IN EN
; ZEXCEPT: XTGUISEP - newed in GUINEXT
I '$D(XTSTVAL) D NVLDARG^%ut1("CHKTF") Q
D CHKTF^%ut1(XTSTVAL,$G(XTERMSG))
I $G(XTERMSG)="" S XTERMSG="no failure message provided"
S %ut("CHK")=$G(%ut("CHK"))+1
I '$D(%utGUI) D
. D SETIO^%ut1
. I 'XTSTVAL W !,%ut("ENT")," - " W:%ut("NAME")'="" %ut("NAME")," - " D
. . W XTERMSG,! S %ut("FAIL")=%ut("FAIL")+1,%utERRL(%ut("FAIL"))=%ut("NAME"),%utERRL(%ut("FAIL"),"MSG")=XTERMSG,%utERRL(%ut("FAIL"),"ENTRY")=%ut("ENT")
. . I $D(%ut("BREAK")) BREAK ; Break upon failure
. . Q
. I XTSTVAL W "."
. D RESETIO^%ut1
. Q
I $D(%utGUI),'XTSTVAL S %ut("CNT")=%ut("CNT")+1,@%ut("RSLT")@(%ut("CNT"))=%ut("LOC")_XTGUISEP_"FAILURE"_XTGUISEP_XTERMSG,%ut("FAIL")=%ut("FAIL")+1
Q
;
CHKEQ(XTEXPECT,XTACTUAL,XTERMSG) ; Entry point for checking values to see if they are EQUAL
N FAILMSG
; ZEXCEPT: %utERRL,%utGUI -CREATED IN SETUP, KILLED IN END
; ZEXCEPT: %ut -- NEWED IN EN
; ZEXCEPT: XTGUISEP - newed in GUINEXT
I '$D(XTEXPECT)!'$D(XTACTUAL) D NVLDARG^%ut1("CHKEQ") Q
D CHKEQ^%ut1(XTEXPECT,XTACTUAL,$G(XTERMSG))
S XTACTUAL=$G(XTACTUAL),XTEXPECT=$G(XTEXPECT)
I $G(XTERMSG)="" S XTERMSG="no failure message provided"
S %ut("CHK")=%ut("CHK")+1
I XTEXPECT'=XTACTUAL S FAILMSG="<"_XTEXPECT_"> vs <"_XTACTUAL_"> - "
I '$D(%utGUI) D
. D SETIO^%ut1
. I XTEXPECT'=XTACTUAL W !,%ut("ENT")," - " W:%ut("NAME")'="" %ut("NAME")," - " W FAILMSG,XTERMSG,! D
. . S %ut("FAIL")=%ut("FAIL")+1,%utERRL(%ut("FAIL"))=%ut("NAME"),%utERRL(%ut("FAIL"),"MSG")=XTERMSG,%utERRL(%ut("FAIL"),"ENTRY")=%ut("ENT")
. . I $D(%ut("BREAK")) BREAK ; Break upon failure
. . Q
. E W "."
. D RESETIO^%ut1
. Q
I $D(%utGUI),XTEXPECT'=XTACTUAL S %ut("CNT")=%ut("CNT")+1,@%ut("RSLT")@(%ut("CNT"))=%ut("LOC")_XTGUISEP_"FAILURE"_XTGUISEP_FAILMSG_XTERMSG,%ut("FAIL")=%ut("FAIL")+1
Q
;
FAIL(XTERMSG) ; Entry point for generating a failure message
@ -240,7 +271,8 @@ ISUTEST() ; .SUPPORTED API TO DETERMINE IF CURRENTLY IN UNIT TEST
Q $G(%ut)=1
;
PICKSET ; .OPT Interactive selection of MUnit Test Group
N DIC,Y,%utROU,%utLIST,DIR S DIC=17.9001,DIC(0)="AEQM" D ^DIC Q:Y'>0 W ! D GETSET(+Y,.%utROU,.%utLIST) N DIC,Y,%ut D SETUT D EN1(.%utROU,%utLIST) S DIR(0)="EA",DIR("A")="Enter RETURN to continue:" D ^DIR K DIR
N DIC,Y,%utROU,%utLIST,DIR
I '$$ISUTEST^%ut() S DIC=17.9001,DIC(0)="AEQM" D ^DIC Q:Y'>0 W ! D GETSET(+Y,.%utROU,.%utLIST) N DIC,Y,%ut D SETUT D EN1(.%utROU,%utLIST) S DIR(0)="EA",DIR("A")="Enter RETURN to continue:" D ^DIR K DIR
Q
;
RUNSET(SETNAME,VERBOSE) ; .SR Run with Specified Selection of MUnit Test Group

View File

@ -1,4 +1,4 @@
%ut1 ;VEN/SMH/JLI - CONTINUATION OF M-UNIT PROCESSING ;09/14/15 09:37
%ut1 ;VEN/SMH/JLI - CONTINUATION OF M-UNIT PROCESSING ;12/07/15 15:34
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Joel L. Ivey as XTMUNIT1 while working for U.S. Department of Veterans Affairs 2003-2012
@ -16,60 +16,6 @@
; Original by Dr. Joel Ivey
; Major contributions by Dr. Sam Habiel
;
; Changes:
; 130726 SMH - Moved test collection logic from %utUNIT to here (multiple places)
; 131218 SMH - dependence on XLFSTR removed
; 131218 SMH - CHEKTEST refactored to use $TEXT instead of ^%ZOSF("LOAD")
; 131218 SMH - CATCHERR now nulls out $ZS if on GT.M
;
; ------- COMMENTS moved from %ut due to space requirements
;
; 100622 JLI - corrected typo in comments where %utINPT was listed as %utINP
; 100622 JLI - removed a comment which indicated data could potentially be returned from the called routine
; in the %utINPT array.
; 100622 JLI - added code to handle STARTUP and SHUTDOWN from GUI app
; 110719 JLI - modified separators in GUI handling from ^ to ~~^~~
; in the variable XTGUISEP if using a newer version of the
; GUI app (otherwise, it is simply set to ^) since results
; with a series of ^ embedded disturbed the output reported
; 130726 SMH - Fixed SETUP and TEARDOWN so that they run before/after each
; test rather than once. General refactoring.
; 130726 SMH - SETUT initialized IO in case it's not there to $P. Inits vars
; using DT^DICRW.
; 131217 SMH - Change call in SETUP to S U="^" instead of DT^DICRW
; 131218 SMH - Any checks to $ZE will also check $ZS for GT.M.
; 131218 SMH - Remove calls to %ZISUTL to manage devices to prevent dependence on VISTA.
; Use %utNIT("DEV","OLD") for old devices
; 140109 SMH - Add parameter %utBREAK - Break upon error
; 1402 SMH - Break will cause the break to happen even on failed tests.
; 140401 SMH - Added Succeed entry point for take it into your hands tester.
; 140401 SMH - Reformatted the output of M-Unit so that the test's name
; will print BEFORE the execution of the test. This has been
; really confusing for beginning users of M-Unit, so this was
; necessary.
; 140401 SMH - OK message gets printed at the end of --- as [OK].
; 140401 SMH - FAIL message now prints. Previously, OK failed to be printed.
; Unfortunately, that's rather passive aggressive. Now it
; explicitly says that a test failed.
; 140503 SMH - Fixed IO issues all over the routine. Much simpler now.
; 140731 JLI - Combined routine changes between JLI and SMH
; Moved routines from %utNIT and %utNIT1 to %ut and %ut1
; Updated unit test routines (%utt1 to %utt6)
; Created M-UNIT TEST GROUP file at 17.9001 based on the 17.9001 file
; 141030 JLI - Removed tag TESTCOVR and code under it, not necessary
; since %uttcovr can handle all of the calling needed
; Added call to run routine %utt6 if run from the top,
; since this will run the full range of unit tests
; Modified STARTUP and SHUTDOWN commands to handle in
; each routine where they are available, since only
; running one STARTUP and SHUTDOWN (the first seen by
; the program) restricted their use in suites of multiple
; tests.
; 150101 JLI - Added COV entry to %ut (in addition to current in %ut1) so it is easier
; to remember how to use it.
; 150621 JLI - Added a global location to pick up summary data for a unit test call, so
; programs running multiple calls can generate a summary if desired.
;
;
CHEKTEST(%utROU,%ut,%utUETRY) ; Collect Test list.
; %utROU - input - Name of routine to check for tags with @TEST attribute
@ -134,47 +80,6 @@ CHECKTAG(LINE) ; JLI 140726 check line to determine @test TAG
S TAG=TAG_U_LINE
Q TAG
;
CHKTF(XTSTVAL,XTERMSG) ; Entry point for checking True or False values
; ZEXCEPT: %utERRL,%utGUI - CREATED IN SETUP, KILLED IN END
; ZEXCEPT: %ut - NEWED IN EN
; ZEXCEPT: XTGUISEP - newed in GUINEXT
I '$D(XTSTVAL) D NVLDARG("CHKTF") Q
I $G(XTERMSG)="" S XTERMSG="no failure message provided"
S %ut("CHK")=$G(%ut("CHK"))+1
I '$D(%utGUI) D
. D SETIO
. I 'XTSTVAL W !,%ut("ENT")," - " W:%ut("NAME")'="" %ut("NAME")," - " D
. . W XTERMSG,! S %ut("FAIL")=%ut("FAIL")+1,%utERRL(%ut("FAIL"))=%ut("NAME"),%utERRL(%ut("FAIL"),"MSG")=XTERMSG,%utERRL(%ut("FAIL"),"ENTRY")=%ut("ENT")
. . I $D(%ut("BREAK")) BREAK ; Break upon failure
. . Q
. I XTSTVAL W "."
. D RESETIO
. Q
I $D(%utGUI),'XTSTVAL S %ut("CNT")=%ut("CNT")+1,@%ut("RSLT")@(%ut("CNT"))=%ut("LOC")_XTGUISEP_"FAILURE"_XTGUISEP_XTERMSG,%ut("FAIL")=%ut("FAIL")+1
Q
;
CHKEQ(XTEXPECT,XTACTUAL,XTERMSG) ; Entry point for checking values to see if they are EQUAL
N FAILMSG
; ZEXCEPT: %utERRL,%utGUI -CREATED IN SETUP, KILLED IN END
; ZEXCEPT: %ut -- NEWED IN EN
; ZEXCEPT: XTGUISEP - newed in GUINEXT
I '$D(XTEXPECT)!'$D(XTACTUAL) D NVLDARG("CHKEQ") Q
S XTACTUAL=$G(XTACTUAL),XTEXPECT=$G(XTEXPECT)
I $G(XTERMSG)="" S XTERMSG="no failure message provided"
S %ut("CHK")=%ut("CHK")+1
I XTEXPECT'=XTACTUAL S FAILMSG="<"_XTEXPECT_"> vs <"_XTACTUAL_"> - "
I '$D(%utGUI) D
. D SETIO
. I XTEXPECT'=XTACTUAL W !,%ut("ENT")," - " W:%ut("NAME")'="" %ut("NAME")," - " W FAILMSG,XTERMSG,! D
. . S %ut("FAIL")=%ut("FAIL")+1,%utERRL(%ut("FAIL"))=%ut("NAME"),%utERRL(%ut("FAIL"),"MSG")=XTERMSG,%utERRL(%ut("FAIL"),"ENTRY")=%ut("ENT")
. . I $D(%ut("BREAK")) BREAK ; Break upon failure
. . Q
. E W "."
. D RESETIO
. Q
I $D(%utGUI),XTEXPECT'=XTACTUAL S %ut("CNT")=%ut("CNT")+1,@%ut("RSLT")@(%ut("CNT"))=%ut("LOC")_XTGUISEP_"FAILURE"_XTGUISEP_FAILMSG_XTERMSG,%ut("FAIL")=%ut("FAIL")+1
Q
;
FAIL(XTERMSG) ; Entry point for generating a failure message
; ZEXCEPT: %utERRL,%utGUI -CREATED IN SETUP, KILLED IN END
; ZEXCEPT: %ut -- NEWED ON ENTRY
@ -236,45 +141,74 @@ COV(NMSP,COVCODE,VERBOSITY) ; VEN/SMH - PUBLIC ENTRY POINT; Coverage calculation
; - 3 = Break down by routine and tag, and print lines that didn't execute for each tag.
;
; ZEXCEPT: %utcovxx - SET and KILLED in this code at top level
Q:'(+$SY=47) ; GT.M only!
; ZEXCEPT: %Monitor,%apiOBJ,DecomposeStatus,LineByLine,Start,Stop,System,class - not variables parts of classes
N COVER,COVERSAV,I,NMSP1,RTN,RTNS,ERR,STATUS
I (+$SY=47) D ; GT.M only!
. N %ZR ; GT.M specific
. D SILENT^%RSEL(NMSP,"SRC") ; GT.M specific. On Cache use $O(^$R(RTN)).
. N RN S RN=""
. W !,"Loading routines to test coverage...",!
. F S RN=$O(%ZR(RN)) Q:RN="" W RN," " D
. . N L2 S L2=$T(+2^@RN)
. . S L2=$TR(L2,$C(9,32)) ; Translate spaces and tabs out
. . I $E(L2,1,2)'=";;" K %ZR(RN) ; Not a human produced routine
. ;
. M RTNS=%ZR
. K %ZR
. Q
;
I (+$SY=0) D ; CACHE SPECIFIC
. S NMSP1=NMSP I NMSP["*" S NMSP1=$P(NMSP,"*")
. I $D(^$R(NMSP1)) S RTNS(NMSP1)=""
. I NMSP["*" S RTN=NMSP1 F S RTN=$O(^$R(RTN)) Q:RTN'[NMSP1 S RTNS(RTN)=""
. Q
;
; ZEXCEPT: CTRAP - not really a variable
S VERBOSITY=+$G(VERBOSITY) ; Get 0 if not passed.
N %ZR ; GT.M specific
D SILENT^%RSEL(NMSP,"SRC") ; GT.M specific. On Cache use $O(^$R(RTN)).
;
N RN S RN=""
W !,"Loading routines to test coverage...",!
F S RN=$O(%ZR(RN)) Q:RN="" W RN," " D
. N L2 S L2=$T(+2^@RN)
. S L2=$TR(L2,$C(9,32)) ; Translate spaces and tabs out
. I $E(L2,1,2)'=";;" K %ZR(RN) ; Not a human produced routine
;
N RTNS M RTNS=%ZR
K %ZR
;
N GL
S GL=$NA(^TMP("%utCOVCOHORT",$J))
I '$D(^TMP("%utcovrunning",$J)) K @GL
D RTNANAL(.RTNS,GL)
I '$D(^TMP("%utcovrunning",$J)) D
D RTNANAL(.RTNS,GL) ; save off any current coverage data
I '$D(^TMP("%utcovrunning",$J)) N EXIT S EXIT=0 D Q:EXIT
. K ^TMP("%utCOVCOHORTSAV",$J)
. M ^TMP("%utCOVCOHORTSAV",$J)=^TMP("%utCOVCOHORT",$J)
. K ^TMP("%utCOVRESULT",$J)
. S ^TMP("%utcovrunning",$J)=1,%utcovxx=1
. VIEW "TRACE":1:$NA(^TMP("%utCOVRESULT",$J)) ; GT.M START PROFILING
. ;
. I (+$SY=47) VIEW "TRACE":1:$NA(^TMP("%utCOVRESULT",$J)) ; GT.M START PROFILING
. ;
. I (+$SY=0) D ; CACHE CODE TO START PROFILING
. . S STATUS=##class(%Monitor.System.LineByLine).Start($lb(NMSP),$lb("RtnLine"),$lb($j))
. . I +STATUS'=1 D DecomposeStatus^%apiOBJ(STATUS,.ERR,"-d") F I=1:1:ERR W ERR(I),!
. . I +STATUS'=1 K ERR S EXIT=1
. . Q
. Q
DO ; Run the code, but keep our variables to ourselves.
. NEW $ETRAP,$ESTACK
. SET $ETRAP="Q:($ES&$Q) -9 Q:$ES W ""CTRL-C ENTERED"""
. USE $PRINCIPAL:(CTRAP=$C(3))
. I (+$SY=47) D ; GT.M SPECIFIC
. . SET $ETRAP="Q:($ES&$Q) -9 Q:$ES W ""CTRL-C ENTERED"""
. . USE $PRINCIPAL:(CTRAP=$C(3))
. . Q
. NEW (DUZ,IO,COVCODE,U,DILOCKTM,DISYS,DT,DTIME,IOBS,IOF,IOM,ION,IOS,IOSL,IOST,IOT,IOXY)
. XECUTE COVCODE
. Q
; GT.M STOP PROFILING if this is the original level that started it
I $D(^TMP("%utcovrunning",$J)),$D(%utcovxx) VIEW "TRACE":0:$NA(^TMP("%utCOVRESULT",$J)) K %utcovxx,^TMP("%utcovrunning",$J)
I $D(^TMP("%utcovrunning",$J)),$D(%utcovxx) D
. I (+$SY=47) VIEW "TRACE":0:$NA(^TMP("%utCOVRESULT",$J)) ; GT.M SPECIFIC
. I (+$SY=0) ; CACHE SPECIFIC
. K %utcovxx,^TMP("%utcovrunning",$J)
. Q
;
I '$D(^TMP("%utcovrunning",$J)) D
. I (+$SY=0) D ; CACHE SPECIFIC CODE
. . S COVERSAV=$NA(^TMP("%utCOVCOHORTSAV",$J)) K @COVERSAV
. . S COVER=$NA(^TMP("%utCOVCOHORT",$J)) K @COVER
. . D CACHECOV(COVERSAV,COVER)
. . D TOTAGS(COVERSAV,0),TOTAGS(COVER,1)
. . D ##class(%Monitor.System.LineByLine).Stop()
. . Q
. D COVCOV($NA(^TMP("%utCOVCOHORT",$J)),$NA(^TMP("%utCOVRESULT",$J))) ; Venn diagram matching between globals
. ; Report
. I VERBOSITY=-1 D
@ -285,6 +219,69 @@ COV(NMSP,COVCODE,VERBOSITY) ; VEN/SMH - PUBLIC ENTRY POINT; Coverage calculation
. Q
QUIT
;
CACHECOV(GLOBSAV,GLOB) ;
; ZEXCEPT: %Monitor,GetMetrics,GetRoutineCount,GetRoutineName,LineByLine,System,class - not variable names, part of classes
N DIF,I,METRIC,METRICNT,METRICS,MTRICNUM,ROUNAME,ROUNUM,X,XCNP,XXX
I $$ISUTEST(),'$D(^TMP("%utt4val",$J)) S ROUNUM=1,METRICS="RtnLine",METRICNT=1,ROUNAME="%ut"
I $D(^TMP("%utt4val",$J))!'$$ISUTEST() S ROUNUM=##class(%Monitor.System.LineByLine).GetRoutineCount(),METRICS=##class(%Monitor.System.LineByLine).GetMetrics(),METRICNT=$l(METRICS,",")
; if only running to do coverage, should be 1
S MTRICNUM=0 F I=1:1:METRICNT S METRIC=$P(METRICS,",",I) I METRIC="RtnLine" S MTRICNUM=I Q
;
F I=1:1:ROUNUM D
. I $D(^TMP("%utt4val",$J))!'$$ISUTEST() S ROUNAME=##class(%Monitor.System.LineByLine).GetRoutineName(I)
. ; get routine loaded into location
. S DIF=$NA(@GLOBSAV@(ROUNAME)),DIF=$E(DIF,1,$L(DIF)-1)_",",XCNP=0,X=ROUNAME
. X ^%ZOSF("LOAD")
. M @GLOB@(ROUNAME)=@GLOBSAV@(ROUNAME)
. Q
;
I $D(^TMP("%utt4val",$J))!'$$ISUTEST() F XXX=1:1:ROUNUM D GETVALS(XXX,GLOB,MTRICNUM)
Q
;
GETVALS(ROUNUM,GLOB,MTRICNUM) ; get data on number of times a line seen (set into VAL)
; ZEXCEPT: %Monitor,%New,%ResultSet,Execute,GetData,GetRoutineName,LineByLine,Next,System,class - not variables parts of Cache classes
N LINE,MORE,ROUNAME,RSET,VAL,X
;
S RSET=##class(%ResultSet).%New("%Monitor.System.LineByLine:Result")
S ROUNAME=##class(%Monitor.System.LineByLine).GetRoutineName(ROUNUM)
S LINE=RSET.Execute(ROUNAME)
F LINE=1:1 S MORE=RSET.Next() Q:'MORE D
. S X=RSET.GetData(1)
. S VAL=$LI(X,MTRICNUM)
. S @GLOB@(ROUNAME,LINE,"C")=+VAL ; values are 0 if not seen, otherwises positive number
. Q
D RSET.Close()
Q
;
TOTAGS(GLOBAL,ACTIVE) ; convert to lines from tags and set value only if not seen
N ACTIVCOD,LINE,LINENUM,ROU,ROUCODE
S ROU="" F S ROU=$O(@GLOBAL@(ROU)) Q:ROU="" D
. M ROUCODE(ROU)=@GLOBAL@(ROU) K @GLOBAL@(ROU)
. N TAG,OFFSET,OLDTAG S TAG="",OFFSET=0,OLDTAG=""
. F LINENUM=1:1 Q:'$D(ROUCODE(ROU,LINENUM,0)) D
. . S LINE=ROUCODE(ROU,LINENUM,0)
. . S ACTIVCOD=$$LINEDATA(LINE,.TAG,.OFFSET)
. . I TAG'=OLDTAG S @GLOBAL@(ROU,TAG)=TAG
. . I ACTIVE,ACTIVCOD,(+$G(ROUCODE(ROU,LINENUM,"C"))'>0) S @GLOBAL@(ROU,TAG,OFFSET)=LINE
. . I 'ACTIVE,ACTIVCOD S @GLOBAL@(ROU,TAG,OFFSET)=LINE
. . Q
. Q
Q
;
LINEDATA(LINE,TAG,OFFSET) ;
; LINE - input - the line of code
; TAG - passed by reference -
; OFFSET - passed by reference
N CODE,NEWTAG
S NEWTAG=""
S OFFSET=$G(OFFSET)+1
F Q:$E(LINE,1)=" " Q:$E(LINE,1)=$C(9) Q:LINE="" S NEWTAG=NEWTAG_$E(LINE,1),LINE=$E(LINE,2,$L(LINE))
S NEWTAG=$P(NEWTAG,"(")
I NEWTAG'="" S TAG=NEWTAG,OFFSET=0
S CODE=1
F S:(LINE="")!($E(LINE)=";") CODE=0 Q:'CODE Q:(" ."'[$E(LINE)) S LINE=$E(LINE,2,$L(LINE))
Q CODE
;
RTNANAL(RTNS,GL) ; [Private] - Routine Analysis
; Create a global similar to the trace global produced by GT.M in GL
; Only non-comment lines are stored.
@ -369,7 +366,7 @@ COVRPTLS(C,S,R,V,X) ;
;W "LEFT: "_LEFTLINES,!
S LINNUM=LINNUM+1,@X@(LINNUM)="LEFT: "_LEFTLINES
;W "COVERAGE PERCENTAGE: "_$S(ORIGLINES:$J(ORIGLINES-LEFTLINES/ORIGLINES*100,"",2),1:100.00),!
S LINNUM=LINNUM+1,@X@(LINNUM)="COVERAGE PERCENTAGE: "_$S(ORIGLINES:$J(ORIGLINES-LEFTLINES/ORIGLINES*100,"",2),1:100.00)
S LINNUM=LINNUM+1,@X@(LINNUM)="COVERAGE PERCENTAGE: "_$S(ORIGLINES:$J((ORIGLINES-LEFTLINES)/ORIGLINES*100,"",2),1:100.00)
;W !!
S LINNUM=LINNUM+1,@X@(LINNUM)="",LINNUM=LINNUM+1,@X@(LINNUM)=""
;W "BY ROUTINE:",!
@ -380,8 +377,10 @@ COVRPTLS(C,S,R,V,X) ;
. N O S O=$$ACTLINES($NA(@C@(RTN)))
. N L S L=$$ACTLINES($NA(@S@(RTN)))
. ;W ?3,RTN,?21,$S(O:$J(O-L/O*100,"",2),1:"100.00"),!
. N XX S XX=" "_RTN_" ",XX=$E(XX,1,20)
. S LINNUM=LINNUM+1,@X@(LINNUM)=XX+$S(O:$J(O-L/O*100,"",2),1:"100.00")
. N XX,XY S XX=" "_RTN_" ",XX=$E(XX,1,12)
. S XY=" "_$S(O:$J((O-L)/O*100,"",2)_"%",1:"------"),XY=$E(XY,$L(XY)-11,$L(XY))
. ;S LINNUM=LINNUM+1,@X@(LINNUM)=XX_$S(O:$J((O-L)/O*100,"",2)_"%",1:"------")_" "_(O-L)_" out of "_O
. S LINNUM=LINNUM+1,@X@(LINNUM)=XX_XY_" "_(O-L)_" out of "_O
. I V=1 QUIT ; Just print the routine coverage for V=1
. N TAG S TAG=""
. F S TAG=$O(@C@(RTN,TAG)) Q:TAG="" D
@ -389,7 +388,9 @@ COVRPTLS(C,S,R,V,X) ;
. . N L S L=$$ACTLINES($NA(@S@(RTN,TAG)))
. . ;W ?5,TAG,?21,$S(O:$J(O-L/O*100,"",2),1:"100.00"),!
. . S XX=" "_TAG_" ",XX=$E(XX,1,20)
. . S LINNUM=LINNUM+1,@X@(LINNUM)=XX_$S(O:$J(O-L/O*100,"",2),1:"100.00")
. . ;S XY=" ("_(O-L)_"/"_O_")",XY=$E(XY,$L(XY)-11,$L(XY)),XX=XX_XY
. . S XY=" "_$S(O:$J((O-L)/O*100,"",2)_"%",1:"------"),XY=$E(XY,$L(XY)-7,$L(XY))
. . S LINNUM=LINNUM+1,@X@(LINNUM)=XX_XY_" "_(O-L)_" out of "_O
. . I V=2 QUIT ; Just print routine/tags coverage for V=2; V=3 print uncovered lines
. . N LN S LN=""
. . ;F S LN=$O(@S@(RTN,TAG,LN)) Q:LN="" W TAG_"+"_LN_": "_^(LN),!
@ -419,3 +420,5 @@ COVRPTGL(C,S,R,OUT) ; [Private] - Coverage Global for silent invokers
. . F S LN=$O(@S@(RTN,TAG,LN)) Q:LN="" S @OUT@(RTN,TAG,LN)=@S@(RTN,TAG,LN)
QUIT
;
ISUTEST() ;
Q $$ISUTEST^%ut()

View File

@ -1,8 +1,63 @@
%utcover ;JLI - generic coverage and unit test runner ;09/14/15 09:37
%utcover ;JLI - generic coverage and unit test runner ;12/07/15 16:36
;;0.2;MASH UTILITIES;;Sep 14, 2015
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Joel L. Ivey
;
; Changes: (Moved from %ut and %ut1)
; 130726 SMH - Moved test collection logic from %utUNIT to here (multiple places)
; 131218 SMH - dependence on XLFSTR removed
; 131218 SMH - CHEKTEST refactored to use $TEXT instead of ^%ZOSF("LOAD")
; 131218 SMH - CATCHERR now nulls out $ZS if on GT.M
;
; ------- COMMENTS moved from %ut due to space requirements
;
; 100622 JLI - corrected typo in comments where %utINPT was listed as %utINP
; 100622 JLI - removed a comment which indicated data could potentially be returned from the called routine
; in the %utINPT array.
; 100622 JLI - added code to handle STARTUP and SHUTDOWN from GUI app
; 110719 JLI - modified separators in GUI handling from ^ to ~~^~~
; in the variable XTGUISEP if using a newer version of the
; GUI app (otherwise, it is simply set to ^) since results
; with a series of ^ embedded disturbed the output reported
; 130726 SMH - Fixed SETUP and TEARDOWN so that they run before/after each
; test rather than once. General refactoring.
; 130726 SMH - SETUT initialized IO in case it's not there to $P. Inits vars
; using DT^DICRW.
; 131217 SMH - Change call in SETUP to S U="^" instead of DT^DICRW
; 131218 SMH - Any checks to $ZE will also check $ZS for GT.M.
; 131218 SMH - Remove calls to %ZISUTL to manage devices to prevent dependence on VISTA.
; Use %utNIT("DEV","OLD") for old devices
; 140109 SMH - Add parameter %utBREAK - Break upon error
; 1402 SMH - Break will cause the break to happen even on failed tests.
; 140401 SMH - Added Succeed entry point for take it into your hands tester.
; 140401 SMH - Reformatted the output of M-Unit so that the test's name
; will print BEFORE the execution of the test. This has been
; really confusing for beginning users of M-Unit, so this was
; necessary.
; 140401 SMH - OK message gets printed at the end of --- as [OK].
; 140401 SMH - FAIL message now prints. Previously, OK failed to be printed.
; Unfortunately, that's rather passive aggressive. Now it
; explicitly says that a test failed.
; 140503 SMH - Fixed IO issues all over the routine. Much simpler now.
; 140731 JLI - Combined routine changes between JLI and SMH
; Moved routines from %utNIT and %utNIT1 to %ut and %ut1
; Updated unit test routines (%utt1 to %utt6)
; Created M-UNIT TEST GROUP file at 17.9001 based on the 17.9001 file
; 141030 JLI - Removed tag TESTCOVR and code under it, not necessary
; since %uttcovr can handle all of the calling needed
; Added call to run routine %utt6 if run from the top,
; since this will run the full range of unit tests
; Modified STARTUP and SHUTDOWN commands to handle in
; each routine where they are available, since only
; running one STARTUP and SHUTDOWN (the first seen by
; the program) restricted their use in suites of multiple
; tests.
; 150101 JLI - Added COV entry to %ut (in addition to current in %ut1) so it is easier
; to remember how to use it.
; 150621 JLI - Added a global location to pick up summary data for a unit test call, so
; programs running multiple calls can generate a summary if desired.
;
;
D EN^%ut("%uttcovr") ; unit tests
Q
;
@ -66,23 +121,29 @@ COVERAGE(ROUNMSP,TESTROUS,XCLDROUS,RESLTLVL) ; run coverage analysis for multipl
; 3 - Full analysis for each tag, and lists out those lines which were
; not executed during the analysis
;
N I,ROU,TYPE,VAL,XCLUDE
N I,ROU,TYPE,XCLUDE
S RESLTLVL=$G(RESLTLVL,1)
I (RESLTLVL<1) S RESLTLVL=1
I (RESLTLVL>3) S RESLTLVL=3
M ^TMP("%utcover",$J,"TESTROUS")=TESTROUS ;
D COV^%ut1(ROUNMSP,"D COVENTRY^%utcover",-1)
K ^TMP("%utcover",$J,"TESTROUS")
S ROU="" F S ROU=$O(XCLDROUS(ROU)) Q:ROU="" D
. I ROU'=+ROU S XCLUDE(ROU)=""
. F I=1:1 S VAL=$P(XCLDROUS(ROU),",",I) Q:VAL="" S XCLUDE(VAL)=""
. Q
S ROU="" F S ROU=$O(XCLDROUS(ROU)) Q:ROU="" D SETROUS(.XCLUDE,.XCLDROUS,ROU)
N TEXTGLOB S TEXTGLOB=$NA(^TMP("%utcover-text",$J)) K @TEXTGLOB
D LIST(.XCLUDE,RESLTLVL,TEXTGLOB)
F I=1:1 Q:'$D(@TEXTGLOB@(I)) W !,@TEXTGLOB@(I)
K @TEXTGLOB
Q
;
SETROUS(XCLUDE,XCLDROUS,ROU) ;
; XCLUDE - passed by reference - on return contains array with indices as routines to exclude from analysis
; XCLDROUS - passed by referenc - array may contain a comma-delimited list of routines to exclude from analysis
; ROU - input - if non-numberic is name of routine to exclude from analysis
N I,VAL
I ROU'=+ROU S XCLUDE(ROU)=""
F I=1:1 S VAL=$P(XCLDROUS(ROU),",",I) Q:VAL="" S XCLUDE(VAL)=""
Q
;
LIST(XCLDROUS,TYPE,TEXTGLOB,GLOB,LINNUM) ;
; ZEXCEPT: TYPE1 - NEWed and set below for recursion
; input - ROULIST - a comma separated list of routine names that will
@ -103,17 +164,21 @@ LIST(XCLDROUS,TYPE,TEXTGLOB,GLOB,LINNUM) ;
I '$D(GLOB) N GLOB S GLOB=$NA(^TMP("%utCOVREPORT",$J))
D TRIMDATA(.XCLDROUS,GLOB) ; remove undesired routines from data
;
N JOB,NAME,BASE
N JOB,NAME,BASE,TEXT,VAL
S TOTCOV=0,TOTLIN=0
; F NAME="%utCOVREPORT","%utCOVRESULT","%utCOVCOHORT","%utCOVCOHORTSAV" D
I TYPE>1 S ROUNAME="" F S ROUNAME=$O(@GLOB@(ROUNAME)) Q:ROUNAME="" S XVAL=^(ROUNAME) D
. S CURRCOV=$P(XVAL,"/"),CURRLIN=$P(XVAL,"/",2)
. S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="",LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=""
. S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="Routine "_ROUNAME_" "_CURRCOV_" out of "_CURRLIN_" lines covered"_$S(CURRLIN>0:" ("_$P((100*CURRCOV)/CURRLIN,".")_"%)",1:"")
. S TEXT="Routine "_ROUNAME_" ",TEXT=$E(TEXT,1,20)
. I CURRLIN>0 S VAL=" ("_$J((100*CURRCOV)/CURRLIN,"",2),VAL=$E(VAL,$L(VAL)-6,$L(VAL))
. S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=TEXT_" "_$S(CURRLIN>0:VAL_"%)",1:" ------ ")_" "_CURRCOV_" out of "_CURRLIN_" lines covered"
. I TYPE>1 S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=" - "_$S(TYPE=2:"Summary",1:"Detailed Breakdown")
. S TAG="" F S TAG=$O(@GLOB@(ROUNAME,TAG)) Q:TAG="" S XVAL=^(TAG) D
. . S LINCOV=$P(XVAL,"/"),LINTOT=$P(XVAL,"/",2)
. . S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=" Tag "_TAG_"^"_ROUNAME_" "_LINCOV_" out of "_LINTOT_" lines covered"
. . S TEXT=" Tag "_TAG_"^"_ROUNAME_" ",TEXT=$E(TEXT,1,26)
. . I LINTOT>0 S VAL=" ("_$J((100*LINCOV)/LINTOT,"",2),VAL=$E(VAL,$L(VAL)-6,$L(VAL))
. . S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=TEXT_$S(LINTOT>0:VAL_"%)",1:" ------ ")_" "_LINCOV_" out of "_LINTOT_" lines covered"
. . I TYPE=2 Q
. . I LINCOV=LINTOT Q
. . S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=" the following is a list of the lines **NOT** covered"
@ -131,8 +196,8 @@ LIST(XCLDROUS,TYPE,TEXTGLOB,GLOB,LINNUM) ;
S ROUNAME="" F S ROUNAME=$O(@GLOB@(ROUNAME)) Q:ROUNAME="" S XVAL=^(ROUNAME) D
. S CURRCOV=$P(XVAL,"/"),CURRLIN=$P(XVAL,"/",2)
. S TOTCOV=TOTCOV+CURRCOV,TOTLIN=TOTLIN+CURRLIN
. S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="Routine "_ROUNAME_" "_CURRCOV_" out of "_CURRLIN_" lines covered"_$S(CURRLIN>0:" ("_$P((100*CURRCOV)/CURRLIN,".")_"%)",1:"")
. Q
. I CURRLIN>0 S VAL=" ("_$J((100*CURRCOV)/CURRLIN,"",2),VAL=$E(VAL,$L(VAL)-6,$L(VAL))
. S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="Routine "_ROUNAME_" "_$S(CURRLIN>0:VAL_"%)",1:" ------ ")_" "_CURRCOV_" out of "_CURRLIN_" lines covered"
S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="",LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)=""
S LINNUM=LINNUM+1,@TEXTGLOB@(LINNUM)="Overall Analysis "_TOTCOV_" out of "_TOTLIN_" lines covered"_$S(TOTLIN>0:" ("_$P((100*TOTCOV)/TOTLIN,".")_"% coverage)",1:"")
Q

View File

@ -1,4 +1,4 @@
%utt1 ; VEN/SMH-JLI - Testing routines for M-Unit;09/14/15 09:38
%utt1 ; VEN/SMH-JLI - Testing routines for M-Unit;12/07/15 17:00
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Sam H. Habiel 07/2013?04/2014
@ -139,10 +139,25 @@ T8 ; If IO starts with another device, write to that device as if it's the prici
I +$SY=0 C D:"D"
I +$SY=47 C D:(delete)
;D CHKTF(Y["MAIN") ; JLI 140829 commented out, gui doesn't run verbose
D CHKTF((Y["MAIN")!(Z["Ran 1 Routine"),"Write to system during test didn't work")
D CHKTF((Y["MAIN")!(Z["T2 - Test 2"),"Write to system during test didn't work")
S IO=$P
QUIT
;
COVRPTGL ;
N GL1,GL2,GL3,GL4
S GL1=$NA(^TMP("%utCOVCOHORTSAVx",$J)) K @GL1
S GL2=$NA(^TMP("%utCOVCOHORTx",$J)) K @GL2
S GL3=$NA(^TMP("%utCOVRESULTx",$J)) K @GL3
S GL4=$NA(^TMP("%utCOVREPORTx",$J)) K @GL4
D SETGLOBS^%uttcovr(GL1,GL2)
D COVRPTGL^%ut1(GL1,GL2,GL3,GL4)
D CHKEQ($G(@GL4@("%ut1","ACTLINES")),"0/9","Wrong number of lines covered f>>or ACTLINES")
D CHKEQ($G(@GL4@("%ut1","ACTLINES",9))," QUIT CNT","Wrong result for last l>>ine not covered for ACTLINES")
D CHKEQ($G(@GL4@("%ut1","CHEKTEST")),"8/10","Wrong number of lines covered >>for CHEKTEST")
D CHKEQ($G(@GL4@("%ut1","CHEKTEST",39))," . Q","Wrong result for last line >>not covered for CHEKTEST")
K @GL1,@GL2,@GL3,@GL4
Q
;
LO(X) Q $TR(X,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")
; Shortcut methods for M-Unit
CHKTF(X,Y) ;
@ -159,6 +174,7 @@ XTENT ; Entry points
;;T6;Succeed Entry Point
;;T7;Make sure we write to principal even though we are on another device
;;T8;If IO starts with another device, write to that device as if it's the pricipal device
;;COVRPTGL;coverage report returning global
;
XTROU ; Routines containing additional tests
;;%utt2; old %utNITU

View File

@ -1,5 +1,5 @@
%utt4 ; VEN/SMH/JLI - Coverage Test Runner;09/14/15 09:38
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 7
%utt4 ; VEN/SMH/JLI - Coverage Test Runner;12/06/15 19:05
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 1
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Sam H. Habiel 07/2013?04/2014
; Additions and modifications made by Joel L. Ivey 05/2014-08/2015
@ -12,10 +12,11 @@ XTMUNITW ; VEN/SMH - Coverage Test Runner;2014-04-17 3:30 PM
;
MAIN ; @TEST - Test coverage calculations
Q:$D(^TMP("%uttcovr",$J)) ; already running coverage analysis from %uttcovr
Q:'(+$SY=47) ; GT.M ONLY
D COV^%ut1("%utt3","D EN^%ut(""%utt3"",1)",-1) ; Only produce output global.
S ^TMP("%utt4val",$J)=1
D COV^%ut("%utt3","D EN^%ut(""%utt3"",1)",-1) ; Only produce output global.
D CHKEQ^%ut("14/19",^TMP("%utCOVREPORT",$J))
D CHKEQ^%ut("2/5",^TMP("%utCOVREPORT",$J,"%utt3","INTERNAL"))
D CHKTF^%ut($D(^TMP("%utCOVREPORT",$J,"%utt3","T2",4)))
D CHKEQ^%ut("1/1",^TMP("%utCOVREPORT",$J,"%utt3","SETUP"))
K ^TMP("%utt4val",$J)
QUIT

View File

@ -1,4 +1,4 @@
%utt6 ;JLI - Unit tests for MUnit functionality ;09/14/15 09:38
%utt6 ;JLI - Unit tests for MUnit functionality ;12/07/15 16:40
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Joel L. Ivey 05/2014-08/2015
@ -77,12 +77,28 @@ VERBOSE ;
; test will need to be updated to reflect the change(s)
; END OF WARNING -- END OF WARNING -- END OF WARNING
;
SETROUS ; @TEST - generate array with indices of routines to exclude
N ROU,XCLDROUS,ROULIST
S XCLDROUS(1)="ROU1NAME,ROU2NAME"
S XCLDROUS("ROUNAME3")="ROUNAME4,ROUNAME5"
D SETROUS^%utcover(.ROULIST,.XCLDROUS,1)
D CHKTF('$D(ROULIST(1)),"SETROUS returned number for routine")
D CHKTF($D(ROULIST("ROU1NAME")),"Didn't get first name on numeric subscript")
D CHKTF($D(ROULIST("ROU2NAME")),"Didn't get second name on numeric subscript")
D SETROUS^%utcover(.ROULIST,.XCLDROUS,"ROUNAME3")
D CHKTF($D(ROULIST("ROUNAME3")),"Didn't get name for routine argument")
D CHKTF($D(ROULIST("ROUNAME4")),"Didn't get first name on routine subscript")
D CHKTF($D(ROULIST("ROUNAME5")),"Didn't get second name on routine subscript")
Q
;
NEWSTYLE ; tests return of valid new style or @TEST indicators
N LIST
D NEWSTYLE^%ut1(.LIST,"%utt5")
D CHKEQ^%ut(LIST,1,"Returned an incorrect number ("_LIST_") of New Style indicators - should be one")
I LIST>0 D CHKEQ^%ut(LIST(1),"NEWSTYLE^identify new style test indicator functionality","Returned incorrect TAG^reason "_LIST(1))
I LIST>0 D CHKEQ^%ut($G(LIST(2)),"","Returned a value for LIST(2) - should not have any value (i.e., null)")
; the following is basically just for coverage
D PICKSET^%ut
Q
;
CKGUISET ;
@ -90,25 +106,29 @@ CKGUISET ;
I '$D(%utt6var) Q
N MAX
S MAX=$O(^TMP("%utt6_GUISET",$J,""),-1)
D CHKTF^%ut(^TMP("%utt6_GUISET",$J,MAX)["%utt6^NEWSTYLE","GUISET returned incorrect list")
D CHKTF(^TMP("%utt6_GUISET",$J,MAX)["%utt6^NEWSTYLE","GUISET returned incorrect list")
Q
;
CHKCMDLN ; check command line processing of %utt5
; ZEXCEPT: JLIEXPCT,%utt6var - if present NEWed and created in code following VERBOSE tag
I '$D(%utt6var) Q
D CHKTF^%ut($D(^TMP("%utt5_C",$J,JLIEXPCT))=10,"Not enough entries in %utt5 expected "_JLIEXPCT)
D CHKTF^%ut($D(^TMP("%utt5_C",$J,JLIEXPCT+1))=0,"Too many entries in %utt5 expected "_JLIEXPCT)
D CHKTF^%ut($O(^TMP("%utt5_C",$J,1,""))="STARTUP","Incorrect function for entry 1,'"_$O(^TMP("%utt5_C",$J,1,""))_"' should be 'STARTUP'")
D CHKTF^%ut($O(^TMP("%utt5_C",$J,JLIEXPCT,""))="SHUTDOWN","Incorrect function for entry "_JLIEXPCT_", '"_$O(^TMP("%utt5_C",$J,JLIEXPCT,""))_"' should be 'SHUTDOWN'")
D CHKTF($D(^TMP("%utt5_C",$J,JLIEXPCT))=10,"Not enough entries in %utt5 expected "_JLIEXPCT)
D CHKTF($D(^TMP("%utt5_C",$J,JLIEXPCT+1))=0,"Too many entries in %utt5 expected "_JLIEXPCT)
D CHKTF($O(^TMP("%utt5_C",$J,1,""))="STARTUP","Incorrect function for entry 1,'"_$O(^TMP("%utt5_C",$J,1,""))_"' should be 'STARTUP'")
D CHKTF($O(^TMP("%utt5_C",$J,JLIEXPCT,""))="SHUTDOWN","Incorrect function for entry "_JLIEXPCT_", '"_$O(^TMP("%utt5_C",$J,JLIEXPCT,""))_"' should be 'SHUTDOWN'")
Q
;
CHKGUI ; check GUI processing of %utt5
; ZEXCEPT: JLIEXPCT,%utt6var - if present NEWed and created in code following VERBOSE tag
I '$D(%utt6var) Q
D CHKTF^%ut($D(^TMP("%utt5_G",$J,JLIEXPCT))=10,"Not enough entries in %utt5 expected "_JLIEXPCT)
D CHKTF^%ut($D(^TMP("%utt5_G",$J,JLIEXPCT+1))=0,"Too many entries in %utt5 expected "_JLIEXPCT)
D CHKTF^%ut($O(^TMP("%utt5_G",$J,1,""))="STARTUP","Incorrect function for entry 1,'"_$O(^TMP("%utt5Z_G",1,""))_"' should be 'STARTUP'")
D CHKTF^%ut($O(^TMP("%utt5_G",$J,JLIEXPCT,""))="SHUTDOWN","Incorrect function for entry "_JLIEXPCT_", '"_$O(^TMP("%utt5_G",$J,JLIEXPCT,""))_"' should be 'SHUTDOWN'")
D CHKTF($D(^TMP("%utt5_G",$J,JLIEXPCT))=10,"Not enough entries in %utt5 expected "_JLIEXPCT)
D CHKTF($D(^TMP("%utt5_G",$J,JLIEXPCT+1))=0,"Too many entries in %utt5 expected "_JLIEXPCT)
D CHKTF($O(^TMP("%utt5_G",$J,1,""))="STARTUP","Incorrect function for entry 1,'"_$O(^TMP("%utt5Z_G",1,""))_"' should be 'STARTUP'")
D CHKTF($O(^TMP("%utt5_G",$J,JLIEXPCT,""))="SHUTDOWN","Incorrect function for entry "_JLIEXPCT_", '"_$O(^TMP("%utt5_G",$J,JLIEXPCT,""))_"' should be 'SHUTDOWN'")
Q
;
CHKTF(VALUE,MESSAGE) ;
D CHKTF^%ut($G(VALUE),$G(MESSAGE))
Q
;
XTENT ;

View File

@ -1,4 +1,4 @@
%uttcovr ;JIVEYSOFT/JLI - runs coverage tests on %ut and %ut1 routines via unit tests ;09/14/15 09:35
%uttcovr ;JIVEYSOFT/JLI - runs coverage tests on %ut and %ut1 routines via unit tests ;12/07/15 16:46
;;0.2;MASH UTILITIES;;Sep 14, 2015;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Joel L. Ivey
@ -10,11 +10,6 @@
; Have it run the following entry points or, if no ^, call EN^%ut with routine name
S RUNCODE(1)="^%utt1,%utt1,^%utt6,VERBOSE^%utt6,%uttcovr,^%ut,^%ut1,^%utcover"
S RUNCODE("ENTRY^%uttcovr")=""
I '(+$SY=47) D Q ; GT.M only!
. W !,"This coverage analysis is currently only available in GT.M"
. N VAL R !,"Do you want to run the same tests using MULTAPIS Y/N ? ",VAL:$G(DTIME,300) Q:'$T
. I "Yy"[$E(VAL) D MULTAPIS^%ut(.RUNCODE)
. Q
; Have the analysis EXCLUDE the following routines from coverage - unit test routines
S XCLUDE(1)="%utt1,%utt2,%utt3,%utt4,%utt5,%utt6,%uttcovr"
S XCLUDE(2)="%utf2hex" ; a GT.M system file, although it wasn't showing up anyway
@ -64,9 +59,9 @@ RTNANAL ; @TEST - routine analysis
S ROUS("%utt4")=""
S GLB=$NA(^TMP("%uttcovr-rtnanal",$J)) K @GLB
D RTNANAL^%ut1(.ROUS,GLB)
D CHKTF^%ut($D(@GLB@("%utt4","MAIN"))>1,"Not enough 'MAIN' nodes found")
D CHKTF^%ut($G(@GLB@("%utt4","MAIN",2))["+$SY=47","Check for GT.M not found in expected line")
D CHKTF^%ut($G(@GLB@("%utt4","MAIN",8))=" QUIT","Final QUIT not on expected line")
D CHKTF($D(@GLB@("%utt4","MAIN"))>1,"Not enough 'MAIN' nodes found")
D CHKTF($G(@GLB@("%utt4","MAIN",3))["D COV^%ut(""%utt3"",""D EN^%ut(""""%utt3"""",1)"",-1)","Incorrect data for line 2 in MAIN")
D CHKTF($G(@GLB@("%utt4","MAIN",9))=" QUIT","Final QUIT not on expected line")
K @GLB
Q
;
@ -88,30 +83,15 @@ COVCOV ; @TEST - check COVCOV - remove seen lines
S @C@("ROU3","TAG1",5)="EAA",@R@("ROU3","TAG1",5)="EAA"
S @C@("ROU3","TAG1",6)="FAA",@R@("ROU3","TAG1",6)="FAA"
D COVCOV^%ut1(C,R)
D CHKTF^%ut($D(@C@("ROU2","TAG1",1)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF^%ut('$D(@C@("ROU2","TAG1",2)),"Unexpected value for ""ROU2"",""TAG1"",1")
D CHKTF^%ut($D(@C@("ROU2","TAG2",6)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF^%ut('$D(@C@("ROU2","TAG2",7)),"Unexpected value for ""ROU2"",""TAG1"",1")
D CHKTF^%ut($D(@C@("ROU3","TAG1",4)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF^%ut('$D(@C@("ROU3","TAG1",5)),"Unexpected value for ""ROU2"",""TAG1"",1")
D CHKTF($D(@C@("ROU2","TAG1",1)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF('$D(@C@("ROU2","TAG1",2)),"Unexpected value for ""ROU2"",""TAG1"",1")
D CHKTF($D(@C@("ROU2","TAG2",6)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF('$D(@C@("ROU2","TAG2",7)),"Unexpected value for ""ROU2"",""TAG1"",1")
D CHKTF($D(@C@("ROU3","TAG1",4)),"Invalid value for ""ROU2"",""TAG1"",1")
D CHKTF('$D(@C@("ROU3","TAG1",5)),"Unexpected value for ""ROU2"",""TAG1"",1")
K @C,@R
Q
;
COVRPTGL ; @TEST - coverage report returning global
N GL1,GL2,GL3,GL4
S GL1=$NA(^TMP("%utCOVCOHORTSAVx",$J)) K @GL1
S GL2=$NA(^TMP("%utCOVCOHORTx",$J)) K @GL2
S GL3=$NA(^TMP("%utCOVRESULTx",$J)) K @GL3
S GL4=$NA(^TMP("%utCOVREPORTx",$J)) K @GL4
D SETGLOBS(GL1,GL2)
D COVRPTGL^%ut1(GL1,GL2,GL3,GL4)
D CHKEQ^%ut($G(@GL4@("%ut1","ACTLINES")),"0/9","Wrong number of lines covered f>>or ACTLINES")
D CHKEQ^%ut($G(@GL4@("%ut1","ACTLINES",9))," QUIT CNT","Wrong result for last l>>ine not covered for ACTLINES")
D CHKEQ^%ut($G(@GL4@("%ut1","CHEKTEST")),"8/10","Wrong number of lines covered >>for CHEKTEST")
D CHKEQ^%ut($G(@GL4@("%ut1","CHEKTEST",39))," . Q","Wrong result for last line >>not covered for CHEKTEST")
K @GL1,@GL2,@GL3,@GL4
Q
;
COVRPT ; @TEST
N GL1,GL2,GL3,GL4,VRBOSITY,GL5
S GL1=$NA(^TMP("%utCOVCOHORTSAVx",$J)) K @GL1
@ -122,24 +102,23 @@ COVRPT ; @TEST
D SETGLOBS(GL1,GL2)
S VRBOSITY=1
D COVRPT^%ut1(GL1,GL2,GL3,VRBOSITY)
D CHKEQ^%ut("COVERAGE PERCENTAGE: 42.11",$G(@GL5@(5)),"Verbosity 1 - not expected percentage value")
D CHKEQ^%ut("42.11",$G(@GL5@(9)),"Verbosity 1 - not expected value for line 9")
D CHKTF^%ut('$D(@GL5@(10)),"Verbosity 1 - unexpected data in 10th line")
D CHKEQ("COVERAGE PERCENTAGE: 42.11",$G(@GL5@(5)),"Verbosity 1 - not expected percentage value")
D CHKEQ(" %ut1 42.11% 8 out of 19",$G(@GL5@(9)),"Verbosity 1 - not expected value for line 9")
D CHKTF('$D(@GL5@(10)),"Verbosity 1 - unexpected data in 10th line")
;
S VRBOSITY=2
D COVRPT^%ut1(GL1,GL2,GL3,VRBOSITY)
D CHKEQ^%ut(" ACTLINES 0.00",$G(@GL5@(10)),"Verbosity 2 - not expected value for 10th line")
D CHKEQ^%ut(" CHEKTEST 80.00",$G(@GL5@(11)),"Verbosity 2 - not expected value for 11th line")
D CHKTF^%ut('$D(@GL5@(12)),"Verbosity 2 - unexpected data for 12th line")
D CHKEQ(" ACTLINES 0.00% 0 out of 9",$G(@GL5@(10)),"Verbosity 2 - not expected value for 10th line")
D CHKEQ(" CHEKTEST 80.00% 8 out of 10",$G(@GL5@(11)),"Verbosity 2 - not expected value for 11th line")
D CHKTF('$D(@GL5@(12)),"Verbosity 2 - unexpected data for 12th line")
;
S VRBOSITY=3
D COVRPT^%ut1(GL1,GL2,GL3,VRBOSITY)
D CHKEQ^%ut(" ACTLINES 0.00",$G(@GL5@(10)),"Verbosity 3 - unexpected value for line 10")
D CHKEQ^%ut("ACTLINES+9: QUIT CNT",$G(@GL5@(19)),"Verbosity 3 - unexpected value for line 19")
D CHKEQ^%ut(" CHEKTEST 80.00",$G(@GL5@(20)),"Verbosity 3 - unexpected value for line 20")
D CHKEQ^%ut("CHEKTEST+39: . Q",$G(@GL5@(22)),"Verbosity 3 - unexpected value for line 22")
D CHKTF^%ut('$D(@GL5@(23)),"Verbosity 3 - unexpected line 23")
;
D CHKEQ(" ACTLINES 0.00% 0 out of 9",$G(@GL5@(10)),"Verbosity 3 - unexpected value for line 10")
D CHKEQ("ACTLINES+9: QUIT CNT",$G(@GL5@(19)),"Verbosity 3 - unexpected value for line 19")
D CHKEQ(" CHEKTEST 80.00% 8 out of 10",$G(@GL5@(20)),"Verbosity 3 - unexpected value for line 20")
D CHKEQ("CHEKTEST+39: . Q",$G(@GL5@(22)),"Verbosity 3 - unexpected value for line 22")
D CHKTF('$D(@GL5@(23)),"Verbosity 3 - unexpected line 23")
K @GL1,@GL2,@GL3,@GL4,@GL5
Q
;
@ -152,25 +131,25 @@ COVRPTLS ; @TEST - coverage report returning text in global
D SETGLOBS(GL1,GL2)
S VRBOSITY=1
D COVRPTLS^%ut1(GL1,GL2,GL3,VRBOSITY,GL4)
D CHKEQ^%ut("COVERAGE PERCENTAGE: 42.11",$G(@GL4@(5)),"Verbosity 1 - not expected percentage value")
D CHKEQ^%ut("42.11",$G(@GL4@(9)),"Verbosity 1 - not expected value for line 9")
D CHKTF^%ut('$D(@GL4@(10)),"Verbosity 1 - unexpected data in 10th line")
D CHKEQ("COVERAGE PERCENTAGE: 42.11",$G(@GL4@(5)),"Verbosity 1 - not expected percentage value")
D CHKEQ(" %ut1 42.11% 8 out of 19",$G(@GL4@(9)),"Verbosity 1 - not expected value for line 9")
D CHKTF('$D(@GL4@(10)),"Verbosity 1 - unexpected data in 10th line")
K @GL4
;
S VRBOSITY=2
D COVRPTLS^%ut1(GL1,GL2,GL3,VRBOSITY,GL4)
D CHKEQ^%ut(" ACTLINES 0.00",$G(@GL4@(10)),"Verbosity 2 - not expected value for 10th line")
D CHKEQ^%ut(" CHEKTEST 80.00",$G(@GL4@(11)),"Verbosity 2 - not expected value for 11th line")
D CHKTF^%ut('$D(@GL4@(12)),"Verbosity 2 - unexpected data for 12th line")
D CHKEQ(" ACTLINES 0.00% 0 out of 9",$G(@GL4@(10)),"Verbosity 2 - not expected value for 10th line")
D CHKEQ(" CHEKTEST 80.00% 8 out of 10",$G(@GL4@(11)),"Verbosity 2 - not expected value for 11th line")
D CHKTF('$D(@GL4@(12)),"Verbosity 2 - unexpected data for 12th line")
K @GL4
;
S VRBOSITY=3
D COVRPTLS^%ut1(GL1,GL2,GL3,VRBOSITY,GL4)
D CHKEQ^%ut(" ACTLINES 0.00",$G(@GL4@(10)),"Verbosity 3 - unexpected value for line 10")
D CHKEQ^%ut("ACTLINES+9: QUIT CNT",$G(@GL4@(19)),"Verbosity 3 - unexpected value for line 19")
D CHKEQ^%ut(" CHEKTEST 80.00",$G(@GL4@(20)),"Verbosity 3 - unexpected value for line 20")
D CHKEQ^%ut("CHEKTEST+39: . Q",$G(@GL4@(22)),"Verbosity 3 - unexpected value for line 22")
D CHKTF^%ut('$D(@GL4@(23)),"Verbosity 3 - unexpected line 23")
D CHKEQ(" ACTLINES 0.00% 0 out of 9",$G(@GL4@(10)),"Verbosity 3 - unexpected value for line 10")
D CHKEQ("ACTLINES+9: QUIT CNT",$G(@GL4@(19)),"Verbosity 3 - unexpected value for line 19")
D CHKEQ(" CHEKTEST 80.00% 8 out of 10",$G(@GL4@(20)),"Verbosity 3 - unexpected value for line 20")
D CHKEQ("CHEKTEST+39: . Q",$G(@GL4@(22)),"Verbosity 3 - unexpected value for line 22")
D CHKTF('$D(@GL4@(23)),"Verbosity 3 - unexpected line 23")
;
K @GL1,@GL2,@GL3,@GL4
Q
@ -182,8 +161,8 @@ TRIMDATA ; @TEST - TRIMDATA in %utcover
S @GL1@("BAD",1)="1"
S XCLUD("BAD")=""
D TRIMDATA^%utcover(.XCLUD,GL1)
D CHKTF^%ut($D(@GL1@("GOOD")),"GOOD ENTRY WAS REMOVED")
D CHKTF^%ut('$D(@GL1@("BAD")),"ENTRY WAS NOT TRIMMED")
D CHKTF($D(@GL1@("GOOD")),"GOOD ENTRY WAS REMOVED")
D CHKTF('$D(@GL1@("BAD")),"ENTRY WAS NOT TRIMMED")
K @GL1,XCLUD
Q
;
@ -204,24 +183,24 @@ LIST ; @TEST - LIST in %utcover
S @GL1@("%ut1","CHEKTEST")="10/10"
N XCLUD S XCLUD("%utt1")=""
D LIST^%utcover(.XCLUD,1,GLT,GL1)
D CHKEQ^%ut("Routine %ut1 89 out of 160 lines covered (55%)",$G(@GLT@(3)),"Verbosity 1 - Unexpected text for line 3")
D CHKEQ^%ut("Overall Analysis 89 out of 160 lines covered (55% coverage)",$G(@GLT@(6)),"Verbosity 1 - unexpected text for line 6")
D CHKTF^%ut('$D(@GLT@(7)),"Verbosity 1 - Unexpected line 7 present")
D CHKEQ("Routine %ut1 (55.63%) 89 out of 160 lines covered",$G(@GLT@(3)),"Verbosity 1 - Unexpected text for line 3")
D CHKEQ("Overall Analysis 89 out of 160 lines covered (55% coverage)",$G(@GLT@(6)),"Verbosity 1 - unexpected text for line 6")
D CHKTF('$D(@GLT@(7)),"Verbosity 1 - Unexpected line 7 present")
K @GLT
;
D LIST^%utcover(.XCLUD,2,GLT,GL1)
D CHKEQ^%ut(" - Summary",$G(@GLT@(4)),"Verbosity 2 - unexpected text at line 4")
D CHKEQ^%ut(" Tag ACTLINES^%ut1 0 out of 8 lines covered",$G(@GLT@(6)),"Verbosity 2 - unexpected text at line 6")
D CHKEQ^%ut(" Tag CHEKTEST^%ut1 10 out of 10 lines covered",$G(@GLT@(8)),"Verbosity 2 - unexpected text at line 8")
D CHKTF^%ut($D(@GLT@(14)),"Verbosity 2 - expected line at line 14")
D CHKTF^%ut('$D(@GLT@(15)),"Verbosity 2 - unexpected line at line 15")
D CHKEQ(" - Summary",$G(@GLT@(4)),"Verbosity 2 - unexpected text at line 4")
D CHKEQ(" Tag ACTLINES^%ut1 (0.00%) 0 out of 8 lines covered",$G(@GLT@(6)),"Verbosity 2 - unexpected text at line 6")
D CHKEQ(" Tag CHEKTEST^%ut1 (100.00%) 10 out of 10 lines covered",$G(@GLT@(8)),"Verbosity 2 - unexpected text at line 8")
D CHKTF($D(@GLT@(14)),"Verbosity 2 - expected line at line 14")
D CHKTF('$D(@GLT@(15)),"Verbosity 2 - unexpected line at line 15")
K @GLT
;
D LIST^%utcover(.XCLUD,3,GLT,GL1)
D CHKEQ^%ut(" Tag %ut1^%ut1 2 out of 2 lines covered",$G(@GLT@(5)),"Verbosity 3 - Incorrect text at line 5")
D CHKEQ^%ut(" ACTLINES+9 QUIT CNT",$G(@GLT@(15)),"Verbosity 3 - incorrect line 15")
D CHKTF^%ut($D(@GLT@(31)),"Verbosity 3 - expected data in line 31")
D CHKTF^%ut('$D(@GLT@(32)),"Verbosity 3 - did not expect a line 32")
D CHKEQ(" Tag %ut1^%ut1 (100.00%) 2 out of 2 lines covered",$G(@GLT@(5)),"Verbosity 3 - Incorrect text at line 5")
D CHKEQ(" ACTLINES+9 QUIT CNT",$G(@GLT@(15)),"Verbosity 3 - incorrect line 15")
D CHKTF($D(@GLT@(31)),"Verbosity 3 - expected data in line 31")
D CHKTF('$D(@GLT@(32)),"Verbosity 3 - did not expect a line 32")
;
K @GL1,@GLT
Q
@ -263,3 +242,81 @@ SETGLOBS(GL1,GL2) ;
S @GL2@("%ut1","CHEKTEST",39)=" . Q"
Q
;
;
CACHECOV ;@TEST - set up routine for analysis in globals
N GLOB,GLOBT
S GLOB=$NA(^TMP("%uttcovr1",$J)),GLOBT=$NA(@GLOB@("uttcovr2",$J)) K @GLOB,@GLOBT
D CACHECOV^%ut1(GLOB,GLOBT)
D CHKEQ($T(+1^%ut),@GLOB@("%ut",1,0),"BAD FIRST LINE LOADED FOR %ut")
D CHKEQ($T(+14^%ut),@GLOBT@("%ut",14,0),"Bad 14th line loaded for %ut")
K @GLOB,@GLOBT
Q
;
GETVALS ; no test - primarily calls to Cache classes
Q
;
LINEDATA ; @TEST - convert code line to based on tags and offset, and identify active code lines
N CODE,LINE,OFFSET,TAG
S LINE="TEST1 ; COMMENT ON TAG",TAG="",OFFSET=0
S CODE=$$LINEDATA^%ut1(LINE,.TAG,.OFFSET) ;
D CHKEQ(0,CODE,"Tag with comment identified as active code")
D CHKEQ("TEST1",TAG,"Bad tag returned for TEST1")
D CHKEQ(0,OFFSET,"Bad OFFSET returned for TEST1")
;
S LINE=" ; COMMENT ONLY"
S CODE=$$LINEDATA^%ut1(LINE,.TAG,.OFFSET) ;
D CHKEQ(0,CODE,"Comment line identified as active code")
D CHKEQ("TEST1",TAG,"Bad tag returned for TEST1+1")
D CHKEQ(1,OFFSET,"Bad OFFSET returned for TEST1+1")
;
S LINE=" S X=VALUE"
S CODE=$$LINEDATA^%ut1(LINE,.TAG,.OFFSET) ;
D CHKEQ(1,CODE,"Code line NOT identified as active code")
D CHKEQ("TEST1",TAG,"Bad tag returned for TEST1+2")
D CHKEQ(2,OFFSET,"Bad OFFSET returned for TEST1+2")
;
S LINE="TEST2 S X=VALUE"
S CODE=$$LINEDATA^%ut1(LINE,.TAG,.OFFSET) ;
D CHKEQ(1,CODE,"Tag line with code NOT identified as active code")
D CHKEQ("TEST2",TAG,"Bad tag returned for TEST2")
D CHKEQ(0,OFFSET,"Bad OFFSET returned for TEST2")
;
Q
;
TOTAGS ;@TEST - convert from lines of code by line number to lines ordered by tag, line from tag, and only not covered
N ACTIVE,GLOB,GLOBT,X1,X0
S GLOB=$NA(^TMP("%uttcovr",$J)),GLOBT=$NA(@GLOB@("TEST1")) K @GLOB
S @GLOBT@(1,0)="LINE1 ; CODE1 LINE1+0 NOT ACTIVE"
S @GLOBT@(2,0)=" CODE2 LINE+1 SEEN"
S @GLOBT@(2,"C")=2
S @GLOBT@(3,0)=" CODE3 LINE1+2 NOT SEEN"
S @GLOBT@(4,0)="LINE4 CODE4 LINE4+0 SEEN"
S @GLOBT@(4,"C")=5
S @GLOBT@(5,0)=" ; CODE5 LINE4+1 NOT ACTIVE"
S @GLOBT@(6,0)=" CODE6 LINE4+2 COVERED"
S @GLOBT@(6,"C")=2
S @GLOBT@(7,0)="LINE7 CODE7 LINE7+0 NOT COVERED"
S @GLOBT@(8,0)=" CODE8 LINE7+1 NOT COVERED"
S ACTIVE=1
D TOTAGS^%ut1(GLOB,ACTIVE)
D CHKEQ(1,($D(@GLOBT@("LINE1"))#2),"LINE1 TAG NOT IDENTIFIED")
D CHKEQ(1,($D(@GLOBT@("LINE4"))#2),"LINE4 TAG NOT IDENTIFIED")
D CHKEQ(1,($D(@GLOBT@("LINE7"))#2),"LINE7 TAG NOT IDENTIFIED")
D CHKEQ(0,$D(@GLOBT@("LINE1",0)),"LINE1+0 SHOULD NOT BE INCLUDED - IT IS A COMMENT")
D CHKEQ(0,$D(@GLOBT@("LINE1",1)),"LINE1+1 SHOULD NOT BE INCLUDED - IT WAS COVERED")
D CHKEQ(1,$D(@GLOBT@("LINE1",2)),"LINE1+2 SHOULD BE INCLUDED - IT WAS NOT COVERED")
D CHKEQ(0,$D(@GLOBT@("LINE4",0)),"LINE4+0 SHOULD NOT BE INCLUDED - IT WAS COVERED")
D CHKEQ(0,$D(@GLOBT@("LINE4",1)),"LINE4+1 SHOULD NOT BE INCLUDED - IT IS A COMMENT")
D CHKEQ(0,$D(@GLOBT@("LINE4",2)),"LINE4+2 SHOULD NOT BE INCLUDED - IT WAS COVERED")
D CHKEQ(1,$D(@GLOBT@("LINE7",0)),"LINE7+0 SHOULD BE INCLUDED - IT IS NOT COVERED")
D CHKEQ(1,$D(@GLOBT@("LINE7",1)),"LINE7+1 SHOULD BE INCLUDED - IT IS NOT COVERED")
K @GLOB,@GLOBT
Q
;
CHKEQ(EXPECTED,SEEN,COMMENT) ;
D CHKEQ^%ut(EXPECTED,SEEN,$G(COMMENT))
Q
;
CHKTF(VALUE,COMMENT) ;
D CHKTF^%ut(VALUE,$G(COMMENT))
Q

View File

@ -1,6 +1,6 @@
%utPOST ;VEN-SMH/JLI - post install for M-Unit Test software ;09/14/15 12:39
;;0.2;MASH UTILITIES;;;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
%utPOST ;VEN-SMH/JLI - post install for M-Unit Test software ;12/13/15 15:36
;;0.3;MASH UTILITIES;;;Build 1
; Submitted to OSEHRA Dec 07, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Sam H. Habiel 07/2013-04/2014
; Additions and modifications made by Joel L. Ivey 05/2014-08/2015
;

View File

@ -1,6 +1,6 @@
%utPRE ;VEN/SMH/JLI - pre installation routine to set up MASH UTILITIES package and assign %ut routines and globals ;10/08/15 19:11
;;0.2;MASH UTILITIES;;;Build 7
; Submitted to OSEHRA Sep 14, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
%utPRE ;VEN/SMH/JLI - pre installation routine to set up MASH UTILITIES package and assign %ut routines and globals ;12/13/15 15:35
;;0.3;MASH UTILITIES;;;Build 1
; Submitted to OSEHRA Dec 07, 2015 by Joel L. Ivey under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html)
; Original routine authored by Sam H. Habiel 07/2013?04/2014
;
;