Files
dc/sas/sasjs/macros/mpe_dirlist.test.sas
T
dc f1b9484463
Build / Build-and-ng-test (pull_request) Successful in 6m32s
Lighthouse Checks / lighthouse (pull_request) Successful in 18m54s
Build / Build-and-test-development (pull_request) Successful in 35m8s
test(macros): cover mpe_dirlist and mpe_writecheck directly
The service tests exercise the actions through a child session; these call the
macros in place, so the guard and the answers are covered without a request:

  mpe_dirlist      7 assertions - iftrue=0 does nothing, one level, files
                   excluded, three levels, the depth cap, the maxobs cap with
                   TRUNCATED=Y, and a blank parent returning a root path
  mpe_writecheck   5 assertions - iftrue=0 does nothing, a writable folder, a
                   file, a missing path with a reason, and the probe leaving an
                   existing file that already had its old name alone

They live in sasjs/macros beside the macros they test, which works: a test file
in a declared macro folder compiles to sasjsbuild/tests/macros/ and sasjs test
runs it from there.

Two traps, both hit before this passed:

- these macros write JSON to _webout, so the test has to point _webout at a
  temp file while they run and put it back before the term program writes the
  results - the first attempt redirected without restoring and the runner
  reported "No webout was returned by job";
- descriptions in mp_assert must not contain a comma: an unquoted comma splits
  the parameter list and the assertion fails to compile with "All positional
  parameters must precede keyword parameters", which names the call rather than
  the comma.
2026-11-03 09:21:43 +00:00

173 lines
3.8 KiB
SAS

/**
@file
@brief Testing mpe_dirlist macro
@details Covers the guard, the listing shape and the cap. The abort paths
(a relative parent, one carrying macro triggers) are covered by
services/admin/makedata.test.sas, because mp_abort cannot be exercised
inside the test session itself.
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_mkdir.sas
@li mp_assert.sas
@li mpe_dirlist.sas
@author 4GL Apps Ltd
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
and may not be re-distributed or re-sold without the express permission of
4GL Apps Ltd.
@sasjslint {"maxLineLength": 80}
**/
%macro countfolders(libds,outmac);
%global &outmac;
proc sql noprint;
select count(*) into:&outmac from &libds
where filepath is not null and filepath ne '';
quit;
%mend countfolders;
/*
These macros write their JSON answer to _webout. Point it at a temporary
file while they run and put it back afterwards, so the test's own result -
which the term program writes to _webout - still reaches the caller. The
assertions read the work datasets the macros build, not the JSON.
*/
%let _webout_path=%sysfunc(pathname(_webout));
filename _webout temp;
%let root=%sysfunc(pathname(work))/dirlist%mf_getuniquefileref();
%mf_mkdir(&root)
%mf_mkdir(&root/aa)
%mf_mkdir(&root/aa/bb)
%mf_mkdir(&root/aa/bb/cc)
data _null_;
file "&root/plain.txt";
put 'x';
run;
/**
* Test 1 - the iftrue guard: nothing happens, and nothing is created
*/
%mpe_dirlist(iftrue=0)
%mp_assert(
iftrue=(%sysfunc(exist(work.dirlist))=0),
desc=The listing does nothing when iftrue is false,
outds=work.test_results
)
/**
* Test 2 - one level: folders only, the file beside them is not offered
*/
data work.fromjs;
length parent $1000;
parent="&root";
depth=1;
maxobs=2000;
run;
%mpe_dirlist(iftrue=1)
%countfolders(work.dirlist,c2)
%mp_assert(
iftrue=(&c2=1),
desc=One level returns the immediate folder only,
outds=work.test_results
)
data _null_;
set work.dirlist;
call symputx('name2',filename,'l');
call symputx('type2',file_or_folder,'l');
run;
%mp_assert(
iftrue=("%upcase(&name2)"="AA" and "%upcase(&type2)"="FOLDER"),
desc=The file beside it is not offered,
outds=work.test_results
)
/**
* Test 3 - depth and its cap
*/
data work.fromjs;
length parent $1000;
parent="&root";
depth=3;
maxobs=2000;
run;
%mpe_dirlist(iftrue=1)
%countfolders(work.dirlist,c3)
%mp_assert(
iftrue=(&c3=3),
desc=Three levels are returned,
outds=work.test_results
)
data work.fromjs;
length parent $1000;
parent="&root";
depth=9;
maxobs=2000;
run;
%mpe_dirlist(iftrue=1)
%countfolders(work.dirlist,c4)
%mp_assert(
iftrue=(&c4=3),
desc=Depth above three is capped at three,
outds=work.test_results
)
/**
* Test 5 - the row cap, and the flag that says it was hit
*/
data work.fromjs;
length parent $1000;
parent="&root";
depth=3;
maxobs=2;
run;
%mpe_dirlist(iftrue=1)
%countfolders(work.dirlist,c5)
data _null_;
set work.dirinfo;
call symputx('trunc5',truncated,'l');
run;
%mp_assert(
iftrue=(&c5=2 and "%upcase(&trunc5)"="Y"),
desc=Rows are capped by maxobs and dirinfo says so,
outds=work.test_results
)
/**
* Test 6 - a blank parent is the platform roots
*/
data work.fromjs;
length parent $1000;
parent='';
depth=1;
maxobs=50;
run;
%mpe_dirlist(iftrue=1)
%countfolders(work.dirlist,c6)
data _null_;
set work.dirlist(obs=1);
call symputx('rootpath6',filepath,'l');
run;
%mp_assert(
iftrue=(&c6>=1 and "%trim(&rootpath6)" ne ""),
desc=A blank parent returns a root entry with a path,
outds=work.test_results
)
/*
hand _webout back before the results are dumped
*/
filename _webout "&_webout_path" mod;
/**
* dump results to the log for offline inspection
*/
data _null_;
set work.test_results;
putlog 'TEST_RESULT_LINE: ' test_result ' - ' test_description;
run;