mirror of
https://github.com/sasjs/core.git
synced 2026-01-07 09:30:06 +00:00
fix: adding support for multilabel and notsorted formats
included additional test job covering multiple scenarios. Closes #337
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<h4> SAS Macros </h4>
|
||||
@li mddl_dc_difftable.sas
|
||||
@li mp_aligndecimal.sas
|
||||
@li mp_cntlout.sas
|
||||
@li mp_loadformat.sas
|
||||
@li mp_assert.sas
|
||||
@li mp_assertscope.sas
|
||||
@@ -23,9 +24,9 @@ data work.loadfmts;
|
||||
length fmtname $32 start end $10000;
|
||||
eexcl='Y';
|
||||
type='N';
|
||||
do i=1 to 100;
|
||||
fmtname=cats('SASJS_',i,'X');
|
||||
do j=1 to 100;
|
||||
do i=1 to 10;
|
||||
fmtname=cats('SASJS_',put(i,z4.),'X');
|
||||
do j=1 to 20;
|
||||
start=cats(j);
|
||||
end=cats(j+1);
|
||||
%mp_aligndecimal(start,width=16)
|
||||
@@ -38,21 +39,32 @@ run;
|
||||
proc format cntlin=work.loadfmts library=perm.testcat;
|
||||
run;
|
||||
|
||||
/*
|
||||
use actual format data as test baseline, as proc format adds attributes eg
|
||||
min/max etc
|
||||
*/
|
||||
%mp_cntlout(libcat=perm.testcat,cntlout=work.loadfmts2)
|
||||
|
||||
/* make some test data */
|
||||
data work.stagedata;
|
||||
set work.loadfmts;
|
||||
type='N';
|
||||
eexcl='Y';
|
||||
if _n_<150 then deleteme='Yes';
|
||||
else if _n_<250 then label='mod'!!cats(_n_);
|
||||
else if _n_<350 then do;
|
||||
set work.loadfmts2 end=lastobs;
|
||||
by type fmtname;
|
||||
|
||||
if lastobs then do;
|
||||
output;
|
||||
fmtname='NEWFMT'!!cats(_n_,'x'); /* 1 new record */
|
||||
start=cats(_n_);
|
||||
end=cats(_n_+1);
|
||||
%mp_aligndecimal(start,width=16)
|
||||
%mp_aligndecimal(end,width=16)
|
||||
label='newval'!!cats(_N_);
|
||||
label='newval'!!cats(_N_,'X');
|
||||
output;
|
||||
stop;
|
||||
end;
|
||||
else stop;
|
||||
else if last.fmtname then deleteme='Yes'; /* 9 deletions */
|
||||
else if first.fmtname then label='modified '!!cats(_n_); /* 10 changes */
|
||||
|
||||
output;
|
||||
run;
|
||||
|
||||
/* load the above */
|
||||
@@ -71,22 +83,22 @@ run;
|
||||
%mp_assertscope(COMPARE)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(del_test1)=149),
|
||||
iftrue=(%mf_nobs(del_test1)=9),
|
||||
desc=Test 1 - delete obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(add_test1)=100),
|
||||
iftrue=(%mf_nobs(add_test1)=1),
|
||||
desc=Test 1 - add obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(mod_test1)=100),
|
||||
iftrue=(%mf_nobs(mod_test1)=10),
|
||||
desc=Test 1 - mod obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(perm.audit)=7329),
|
||||
iftrue=(%mf_nobs(perm.audit)=440),
|
||||
desc=Test 1 - audit table updated,
|
||||
outds=work.test_results
|
||||
)
|
||||
@@ -101,7 +113,7 @@ run;
|
||||
)
|
||||
|
||||
/* set up a mix of formats */
|
||||
data work.loadfmts2;
|
||||
data work.loadfmts3;
|
||||
length fmtname $32 start end $10000;
|
||||
eexcl='Y';
|
||||
type='J';
|
||||
@@ -150,45 +162,47 @@ data work.loadfmts2;
|
||||
end;
|
||||
drop i j;
|
||||
run;
|
||||
proc format cntlin=work.loadfmts2 library=perm.testcat2;
|
||||
proc format cntlin=work.loadfmts3 library=perm.testcat3;
|
||||
run;
|
||||
%mp_cntlout(libcat=perm.testcat3,cntlout=work.loadfmts4)
|
||||
|
||||
/* make some test data */
|
||||
data work.stagedata2;
|
||||
set work.loadfmts2;
|
||||
data work.stagedata3;
|
||||
set work.loadfmts4;
|
||||
where type in ('I','J');
|
||||
eexcl='Y';
|
||||
by type fmtname notsorted;
|
||||
if type='I' then do;
|
||||
i+1;
|
||||
if i<3 then deleteme='Yes';
|
||||
else if i<7 then label= cats(ranuni(0)*100);
|
||||
else if i<12 then do;
|
||||
/* new values */
|
||||
if last.fmtname then do;
|
||||
deleteme='Yes'; /* 3 deletions */
|
||||
output;
|
||||
end;
|
||||
else if fmtrow le 3 then do; /* 9 changed values */
|
||||
z=ranuni(0)*1000000;
|
||||
start=cats(z);
|
||||
end=cats(z+1);
|
||||
%mp_aligndecimal(start,width=16)
|
||||
%mp_aligndecimal(end,width=16)
|
||||
label= cats(ranuni(0)*100);
|
||||
output;
|
||||
end;
|
||||
if i<12 then output;
|
||||
end;
|
||||
else do;
|
||||
j+1;
|
||||
if j<3 then deleteme='Yes';
|
||||
else if j<7 then label= cats(ranuni(0)*100);
|
||||
else if j<12 then do;
|
||||
start= cats("NEWVAL",start);
|
||||
end=start;
|
||||
label= "NEWVAL "||cats(ranuni(0)*100);
|
||||
if last.fmtname then do;
|
||||
output; /* 6 new records */
|
||||
x=_n_;
|
||||
x+1;start=cats("mod",x);end=start;label='newlabel1';output;
|
||||
x+1;start=cats("mod",x);end=start;label='newlabel2';output;
|
||||
end;
|
||||
else if fmtrow le 3 then do; /* 9 more changed values */
|
||||
start= cats("mod",_n_);
|
||||
end=start;
|
||||
label= "mod "||cats(ranuni(0)*100);
|
||||
output;
|
||||
end;
|
||||
if j<12 then output;
|
||||
end;
|
||||
|
||||
run;
|
||||
|
||||
%mp_loadformat(perm.testcat2
|
||||
,work.stagedata2
|
||||
%mp_loadformat(perm.testcat3
|
||||
,work.stagedata3
|
||||
,loadtarget=YES
|
||||
,auditlibds=perm.audit
|
||||
,locklibds=0
|
||||
@@ -200,17 +214,18 @@ run;
|
||||
)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(del_test2)=4),
|
||||
iftrue=(%mf_nobs(del_test2)=3),
|
||||
desc=Test 2 - delete obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(mod_test2)=8),
|
||||
iftrue=(%mf_nobs(mod_test2)=18),
|
||||
desc=Test 2 - mod obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(add_test2)=10),
|
||||
iftrue=(%mf_nobs(add_test2)=6),
|
||||
desc=Test 2 - add obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
128
tests/base/mp_loadformat.test.2.sas
Normal file
128
tests/base/mp_loadformat.test.2.sas
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
@file
|
||||
@brief Testing mp_loadformat.sas macro for multilabel formats
|
||||
@details Multilabel records can be complete duplicates!! Also, the order is
|
||||
important.
|
||||
|
||||
The provided formats create a table as follows:
|
||||
|
||||
|TYPE:$1.|FMTNAME:$32.|START:$10000.|END:$10000.|LABEL:$32767.|MIN:best.|
|
||||
MAX:best.|DEFAULT:best.|LENGTH:best.|FUZZ:best.|PREFIX:$2.|MULT:best.|FILL:$1.|
|
||||
NOEDIT:best.|SEXCL:$1.|EEXCL:$1.|HLO:$13.|DECSEP:$1.|DIG3SEP:$1.|DATATYPE:$8.|
|
||||
LANGUAGE:$8.|
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
---|---|
|
||||
|`C `|`GENDERML `|` `|` `|`Total people `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`1 `|`1 `|`Male `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`1 `|`1 `|`Total people `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`2 `|`2 `|`Female `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`2 `|`2 `|`Female `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`2 `|`2 `|`Thormale `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`C `|`GENDERML `|`2 `|`2 `|`Total people `|`1 `|`40 `|`12 `|`12 `|`0 `|` `|`0 `|` `|`0 `|`N `|`N `|`M `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLA `|`1 `|`4 `|`Preschool `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLA `|`1 `|`18 `|`Children `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLA `|`19 `|`120 `|`Adults `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLB `|`1 `|`4 `|`Preschool `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLB `|`1 `|`18 `|`Children `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLB `|`19 `|`120 `|`Adults `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLC `|`1 `|`18 `|`Children `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLC `|`1 `|`4 `|`Preschool `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|`N `|`AGEMLC `|`19 `|`120 `|`Adults `|`1 `|`40 `|`9 `|`9 `|`1E-12 `|` `|`0 `|` `|`0 `|`N `|`N `|`SM `|` `|` `|` `|` `|
|
||||
|
||||
<h4> SAS Macros </h4>
|
||||
@li mf_nobs.sas
|
||||
@li mp_cntlout.sas
|
||||
@li mp_loadformat.sas
|
||||
@li mp_assert.sas
|
||||
@li mp_assertdsobs.sas
|
||||
@li mp_ds2md.sas
|
||||
|
||||
**/
|
||||
|
||||
/* prep format catalog */
|
||||
libname perm (work);
|
||||
|
||||
/* create some multilable formats */
|
||||
%let cat1=perm.test1;
|
||||
proc format library=&cat1;
|
||||
value $genderml (multilabel notsorted)
|
||||
'1'='Male'
|
||||
'2'='Female'
|
||||
'2'='Female'
|
||||
'2'='Farmale'
|
||||
'1','2',' '='Total people';
|
||||
value agemla (multilabel)
|
||||
1-4='Preschool'
|
||||
1-18='Children'
|
||||
19-120='Adults';
|
||||
value agemlb (multilabel)
|
||||
19-120='Adults'
|
||||
1-18='Children'
|
||||
1-4='Preschool';
|
||||
value agemlc (multilabel notsorted)
|
||||
19-120='Adults'
|
||||
1-18='Children'
|
||||
1-4='Preschool';
|
||||
run;
|
||||
|
||||
%mp_cntlout(libcat=&cat1,cntlout=work.cntlout1)
|
||||
%mp_assertdsobs(work.cntlout1,
|
||||
desc=Has 16 records,
|
||||
test=EQUALS 16
|
||||
)
|
||||
|
||||
data work.stagedata3;
|
||||
set work.cntlout1;
|
||||
if fmtname='AGEMLA' and label ne 'Preschool' then deleteme='Yes';
|
||||
if fmtname='AGEMLB' and label = 'Preschool' then label='Kids';
|
||||
if fmtname='GENDERML' and label='Farmale' then output;
|
||||
output;
|
||||
run;
|
||||
|
||||
|
||||
%mp_loadformat(&cat1
|
||||
,work.stagedata3
|
||||
,loadtarget=YES
|
||||
,auditlibds=perm.audit
|
||||
,locklibds=0
|
||||
,delete_col=deleteme
|
||||
,outds_add=add_test1
|
||||
,outds_del=del_test1
|
||||
,outds_mod=mod_test1
|
||||
,mdebug=1
|
||||
)
|
||||
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(del_test1)=2),
|
||||
desc=Test 1 - deleted obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(mod_test1)=4),
|
||||
desc=Test 1 - mod obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
%mp_assert(
|
||||
iftrue=(%mf_nobs(add_test1)=1),
|
||||
desc=Test 1 - add obs,
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
/* now check the order of the notsorted format */
|
||||
%mp_cntlout(libcat=&cat1,cntlout=work.cntlout2)
|
||||
|
||||
%let check1=0;
|
||||
%let check2=0;
|
||||
data test;
|
||||
set work.cntlout2;
|
||||
where fmtname='GENDERML';
|
||||
if _n_=4 and label='Farmale' then call symputx('check1',1);
|
||||
if _n_=5 and label='Farmale' then call symputx('check2',1);
|
||||
run;
|
||||
%mp_assert(
|
||||
iftrue=(&check1=1 and &check2=1),
|
||||
desc=Ensuring Farmale values retain their order,
|
||||
outds=work.test_results
|
||||
)
|
||||
|
||||
%mp_ds2md(work.cntlout2)
|
||||
Reference in New Issue
Block a user