diff --git a/all.sas b/all.sas
index 8ea36cd..7205750 100644
--- a/all.sas
+++ b/all.sas
@@ -3032,8 +3032,15 @@ run;
makes it easy to detect whether any macro variables were modified or
changed.
- If you would like this feature, feel free to contribute / raise an issue /
- engage the SASjs team directly.
+ The following variables are NOT tested (as they are known, global variables
+ used in SASjs):
+
+ @li &sasjs_prefix._FUNCTIONS
+
+ Global variables are initialised in mp_init.sas - which will also trigger
+ "strict mode" in your SAS session. Whilst this is a default in SASjs
+ produced apps, if you prefer not to use this mode, simply instantiate the
+ following variable to prevent the macro from running: `SASJS_PREFIX`
Example usage:
@@ -3054,6 +3061,8 @@ run;
@param [in] scope= (GLOBAL) The scope of the variables to be checked. This
corresponds to the values in the SCOPE column in `sashelp.vmacro`.
@param [in] desc= (Testing scope leakage) The user provided test description
+ @param [in] ignorelist= Provide a list of macro variable names to ignore from
+ the comparison
@param [in,out] scopeds= (work.mp_assertscope) The dataset to contain the
scope snapshot
@param [out] outds= (work.test_results) The output dataset to contain the
@@ -3062,6 +3071,10 @@ run;
|---|---|---|
|User Provided description|PASS|No out of scope variables created or modified|
+
SAS Macros
+ @li mf_getquotedstr.sas
+ @li mp_init.sas
+
Related Macros
@li mp_assert.sas
@li mp_assertcols.sas
@@ -3078,9 +3091,18 @@ run;
desc=Testing Scope Leakage,
scope=GLOBAL,
scopeds=work.mp_assertscope,
+ ignorelist=,
outds=work.test_results
)/*/STORE SOURCE*/;
-%local ds test_result test_comments del add mod;
+%local ds test_result test_comments del add mod ilist;
+%let ilist=%upcase(&sasjs_prefix._FUNCTIONS &ignorelist);
+
+/**
+ * this sets up the global vars, it will also enter STRICT mode. If this
+ * behaviour is not desired, simply initiate the following global macro
+ * variable to prevent the macro from running: SASJS_PREFIX
+ */
+%mp_init()
/* get current variables */
%if &action=SNAPSHOT %then %do;
@@ -3088,7 +3110,7 @@ run;
create table &scopeds as
select name,offset,value
from dictionary.macros
- where scope="&scope"
+ where scope="&scope" and name not in (%mf_getquotedstr(&ilist))
order by name,offset;
%end;
%else %if &action=COMPARE %then %do;
@@ -3097,7 +3119,7 @@ run;
create table _data_ as
select name,offset,value
from dictionary.macros
- where scope="&scope"
+ where scope="&scope" and name not in (%mf_getquotedstr(&ilist))
order by name,offset;
%let ds=&syslast;
@@ -10129,7 +10151,7 @@ create table &delrec as
from &outdel a
left join &base b
on &keyjoin
- where a.%scan(&key,1) is null
+ where b.%scan(&key,1) is null
order by &commakey;
data &delerr;
@@ -10237,7 +10259,7 @@ select distinct tgtvar_nm into: missvars separated by ' '
from &outmod a
left join &base b
on &keyjoin
- where a.%scan(&key,1) is null
+ where b.%scan(&key,1) is null
order by &commakey;
data &moderr;
if 0 then set &errds;
diff --git a/base/mp_assertscope.sas b/base/mp_assertscope.sas
index 7910d10..e1dd54c 100644
--- a/base/mp_assertscope.sas
+++ b/base/mp_assertscope.sas
@@ -11,8 +11,15 @@
makes it easy to detect whether any macro variables were modified or
changed.
- If you would like this feature, feel free to contribute / raise an issue /
- engage the SASjs team directly.
+ The following variables are NOT tested (as they are known, global variables
+ used in SASjs):
+
+ @li &sasjs_prefix._FUNCTIONS
+
+ Global variables are initialised in mp_init.sas - which will also trigger
+ "strict mode" in your SAS session. Whilst this is a default in SASjs
+ produced apps, if you prefer not to use this mode, simply instantiate the
+ following variable to prevent the macro from running: `SASJS_PREFIX`
Example usage:
@@ -33,6 +40,8 @@
@param [in] scope= (GLOBAL) The scope of the variables to be checked. This
corresponds to the values in the SCOPE column in `sashelp.vmacro`.
@param [in] desc= (Testing scope leakage) The user provided test description
+ @param [in] ignorelist= Provide a list of macro variable names to ignore from
+ the comparison
@param [in,out] scopeds= (work.mp_assertscope) The dataset to contain the
scope snapshot
@param [out] outds= (work.test_results) The output dataset to contain the
@@ -41,6 +50,10 @@
|---|---|---|
|User Provided description|PASS|No out of scope variables created or modified|
+ SAS Macros
+ @li mf_getquotedstr.sas
+ @li mp_init.sas
+
Related Macros
@li mp_assert.sas
@li mp_assertcols.sas
@@ -57,9 +70,18 @@
desc=Testing Scope Leakage,
scope=GLOBAL,
scopeds=work.mp_assertscope,
+ ignorelist=,
outds=work.test_results
)/*/STORE SOURCE*/;
-%local ds test_result test_comments del add mod;
+%local ds test_result test_comments del add mod ilist;
+%let ilist=%upcase(&sasjs_prefix._FUNCTIONS &ignorelist);
+
+/**
+ * this sets up the global vars, it will also enter STRICT mode. If this
+ * behaviour is not desired, simply initiate the following global macro
+ * variable to prevent the macro from running: SASJS_PREFIX
+ */
+%mp_init()
/* get current variables */
%if &action=SNAPSHOT %then %do;
@@ -67,7 +89,7 @@
create table &scopeds as
select name,offset,value
from dictionary.macros
- where scope="&scope"
+ where scope="&scope" and name not in (%mf_getquotedstr(&ilist))
order by name,offset;
%end;
%else %if &action=COMPARE %then %do;
@@ -76,7 +98,7 @@
create table _data_ as
select name,offset,value
from dictionary.macros
- where scope="&scope"
+ where scope="&scope" and name not in (%mf_getquotedstr(&ilist))
order by name,offset;
%let ds=&syslast;
diff --git a/base/mp_stackdiffs.sas b/base/mp_stackdiffs.sas
index 292a19b..e7fbe56 100644
--- a/base/mp_stackdiffs.sas
+++ b/base/mp_stackdiffs.sas
@@ -418,7 +418,7 @@ create table &delrec as
from &outdel a
left join &base b
on &keyjoin
- where a.%scan(&key,1) is null
+ where b.%scan(&key,1) is null
order by &commakey;
data &delerr;
@@ -526,7 +526,7 @@ select distinct tgtvar_nm into: missvars separated by ' '
from &outmod a
left join &base b
on &keyjoin
- where a.%scan(&key,1) is null
+ where b.%scan(&key,1) is null
order by &commakey;
data &moderr;
if 0 then set &errds;
diff --git a/tests/crossplatform/mp_stackdiffs.test.sas b/tests/crossplatform/mp_stackdiffs.test.sas
index 83f02da..0fccf8d 100644
--- a/tests/crossplatform/mp_stackdiffs.test.sas
+++ b/tests/crossplatform/mp_stackdiffs.test.sas
@@ -45,13 +45,17 @@ run;
%mp_assertscope(SNAPSHOT)
/**
- * Deletions test - where record does not exist
+ * Deletions test - where record does exist
*/
+data work.orig1;
+ set sashelp.electric;
+ if _n_ le 10;
+run;
data work.final1;
set work.final;
where move_type='D';
run;
-%mp_stackdiffs(work.orig
+%mp_stackdiffs(work.orig1
,work.final1
,CUSTOMER YEAR
,mdebug=1
@@ -69,11 +73,11 @@ run;
test=EQUALS 10
)
/**
- * Deletions test - where record DOES exist
+ * Deletions test - where record does NOT exist
*/
data work.orig2;
- set sashelp.electric;
- if _n_ le 10;
+ set work.orig;
+ stop; /* empty table */
run;
data work.final2;
set work.final;
@@ -89,11 +93,11 @@ run;
,outdel=work.del2
)
%mp_assertdsobs(work.errds2,
- desc=Delete1 - has errs,
+ desc=Delete2 - has errs,
test=EQUALS 10
)
%mp_assertdsobs(work.del1,
- desc=Delete1 - records not populated,
+ desc=Delete2 - records not populated,
test=EQUALS 0
)
@@ -130,7 +134,9 @@ run;
* Additions test - where record does exist
*/
data work.orig4;
- set work.orig;
+ set sashelp.electric;
+ if _n_ ge 30;
+ year=_n_;
if _n_>35 then stop;
run;
data work.final4;
@@ -251,7 +257,7 @@ run;
* And a test if the actual values were applied
*/
data work.orig8;
- set work.orig;
+ set sashelp.electric;
if _n_ le 16;
run;
%mp_stackdiffs(work.orig8
@@ -292,4 +298,4 @@ run;
)
-%mp_assertscope(COMPARE,Desc=MacVar Scope Check)
\ No newline at end of file
+%mp_assertscope(COMPARE,ignorelist=SASJS_FUNCTIONS)
\ No newline at end of file