mirror of
https://github.com/sasjs/core.git
synced 2026-01-07 09:30:06 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2d5859675 | ||
|
|
ea057d4655 | ||
|
|
26c085b354 | ||
|
|
d13ac52739 | ||
|
|
bbbc28ad6d | ||
|
|
530cd6e95c | ||
|
|
c4e17e43e8 |
10
.npmignore
Normal file
10
.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
all.sas
|
||||||
|
build.py
|
||||||
|
.gitpod*
|
||||||
|
tests/
|
||||||
|
sasjs/
|
||||||
|
.vscode/
|
||||||
|
.github/
|
||||||
|
main.dox
|
||||||
|
make_singlefile.sh
|
||||||
|
*.md
|
||||||
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
As the changes are managed automatically in github, we don't generate an additional changelog. To view the fixes/features in each release, check out the releases page below:
|
||||||
|
|
||||||
|
[https://github.com/sasjs/core/releases](https://github.com/sasjs/core/releases)
|
||||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
https://sasapps.io/contact-us.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
[](/LICENSE) [](/package.json)   [](https://gitpod.io/#https://github.com/sasjs/core)
|
||||||
|
|
||||||
# Macro Core
|
# Macro Core
|
||||||
|
|
||||||
Much quality. Many standards. The **Macro Core** library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of [Application Development](https://sasapps.io) on the SAS platform (eg https://datacontroller.io). [Contributions](https://github.com/sasjs/core/blob/main/CONTRIBUTING.md) are welcomed.
|
Much quality. Many standards. The **Macro Core** library exists to save time and development effort! Herein ye shall find a veritable host of MIT-licenced, production quality SAS macros. These are a mix of tools, utilities, functions and code generators that are useful in the context of [Application Development](https://sasapps.io) on the SAS platform (eg https://datacontroller.io). [Contributions](https://github.com/sasjs/core/blob/main/CONTRIBUTING.md) are welcomed.
|
||||||
|
|||||||
35
all.sas
35
all.sas
@@ -2179,7 +2179,11 @@ Usage:
|
|||||||
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
||||||
@li HASOBS - Test is a PASS if the input dataset has any observations
|
@li HASOBS - Test is a PASS if the input dataset has any observations
|
||||||
@li EMPTY - Test is a PASS if input dataset is empty
|
@li EMPTY - Test is a PASS if input dataset is empty
|
||||||
@li EQUALS [integer] - Test passes if obs count matches the provided integer
|
@li EQUALS [integer] - Test passes if row count matches the provided integer
|
||||||
|
@LI ATLEAST [integer] - Test passes if row count is more than or equal to
|
||||||
|
the provided integer
|
||||||
|
@LI ATMOST [integer] - Test passes if row count is less than or equal to
|
||||||
|
the provided integer
|
||||||
@param [out] outds= (work.test_results) The output dataset to contain the
|
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||||
results. If it does not exist, it will be created, with the following format:
|
results. If it does not exist, it will be created, with the following format:
|
||||||
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||||
@@ -2188,6 +2192,8 @@ Usage:
|
|||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Macros </h4>
|
||||||
@li mp_assertcolvals.sas
|
@li mp_assertcolvals.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertcols.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -2212,6 +2218,22 @@ Usage:
|
|||||||
)
|
)
|
||||||
%let test=EQUALS;
|
%let test=EQUALS;
|
||||||
%end;
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATLEAST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATLEAST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATLEAST;
|
||||||
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATMOST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATMOST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATMOST;
|
||||||
|
%end;
|
||||||
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
mac=&sysmacroname,
|
mac=&sysmacroname,
|
||||||
@@ -2223,7 +2245,8 @@ Usage:
|
|||||||
length test_description $256 test_result $4 test_comments $256;
|
length test_description $256 test_result $4 test_comments $256;
|
||||||
test_description=symget('desc');
|
test_description=symget('desc');
|
||||||
test_result='FAIL';
|
test_result='FAIL';
|
||||||
test_comments="&sysmacroname: Dataset &inds has &nobs observations";
|
test_comments="&sysmacroname: Dataset &inds has &nobs observations.";
|
||||||
|
test_comments=test_comments!!" Test was "!!symget('test');
|
||||||
%if &test=HASOBS %then %do;
|
%if &test=HASOBS %then %do;
|
||||||
if &nobs>0 then test_result='PASS';
|
if &nobs>0 then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
@@ -2233,6 +2256,12 @@ Usage:
|
|||||||
%else %if &test=EQUALS %then %do;
|
%else %if &test=EQUALS %then %do;
|
||||||
if &nobs=&val then test_result='PASS';
|
if &nobs=&val then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
|
%else %if &test=ATLEAST %then %do;
|
||||||
|
if &nobs ge &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
|
%else %if &test=ATMOST %then %do;
|
||||||
|
if &nobs le &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
||||||
%end;
|
%end;
|
||||||
@@ -2247,7 +2276,7 @@ Usage:
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds;
|
drop table &ds;
|
||||||
|
|
||||||
%mend;/**
|
%mend mp_assertdsobs;/**
|
||||||
@file
|
@file
|
||||||
@brief Copy any file using binary input / output streams
|
@brief Copy any file using binary input / output streams
|
||||||
@details Reads in a file byte by byte and writes it back out. Is an
|
@details Reads in a file byte by byte and writes it back out. Is an
|
||||||
|
|||||||
@@ -18,7 +18,11 @@
|
|||||||
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
@param [in] test= (HASOBS) The test to apply. Valid values are:
|
||||||
@li HASOBS - Test is a PASS if the input dataset has any observations
|
@li HASOBS - Test is a PASS if the input dataset has any observations
|
||||||
@li EMPTY - Test is a PASS if input dataset is empty
|
@li EMPTY - Test is a PASS if input dataset is empty
|
||||||
@li EQUALS [integer] - Test passes if obs count matches the provided integer
|
@li EQUALS [integer] - Test passes if row count matches the provided integer
|
||||||
|
@LI ATLEAST [integer] - Test passes if row count is more than or equal to
|
||||||
|
the provided integer
|
||||||
|
@LI ATMOST [integer] - Test passes if row count is less than or equal to
|
||||||
|
the provided integer
|
||||||
@param [out] outds= (work.test_results) The output dataset to contain the
|
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||||
results. If it does not exist, it will be created, with the following format:
|
results. If it does not exist, it will be created, with the following format:
|
||||||
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||||
@@ -27,6 +31,8 @@
|
|||||||
|
|
||||||
<h4> Related Macros </h4>
|
<h4> Related Macros </h4>
|
||||||
@li mp_assertcolvals.sas
|
@li mp_assertcolvals.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mp_assertcols.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -51,6 +57,22 @@
|
|||||||
)
|
)
|
||||||
%let test=EQUALS;
|
%let test=EQUALS;
|
||||||
%end;
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATLEAST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATLEAST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATLEAST;
|
||||||
|
%end;
|
||||||
|
%else %if %substr(&test.xxxxxxx,1,7)=ATMOST %then %do;
|
||||||
|
%let val=%scan(&test,2,%str( ));
|
||||||
|
%mp_abort(iftrue= (%DATATYP(&val)=CHAR)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid test - &test, expected ATMOST [integer])
|
||||||
|
)
|
||||||
|
%let test=ATMOST;
|
||||||
|
%end;
|
||||||
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
%else %if &test ne HASOBS and &test ne EMPTY %then %do;
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
mac=&sysmacroname,
|
mac=&sysmacroname,
|
||||||
@@ -62,7 +84,8 @@
|
|||||||
length test_description $256 test_result $4 test_comments $256;
|
length test_description $256 test_result $4 test_comments $256;
|
||||||
test_description=symget('desc');
|
test_description=symget('desc');
|
||||||
test_result='FAIL';
|
test_result='FAIL';
|
||||||
test_comments="&sysmacroname: Dataset &inds has &nobs observations";
|
test_comments="&sysmacroname: Dataset &inds has &nobs observations.";
|
||||||
|
test_comments=test_comments!!" Test was "!!symget('test');
|
||||||
%if &test=HASOBS %then %do;
|
%if &test=HASOBS %then %do;
|
||||||
if &nobs>0 then test_result='PASS';
|
if &nobs>0 then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
@@ -72,6 +95,12 @@
|
|||||||
%else %if &test=EQUALS %then %do;
|
%else %if &test=EQUALS %then %do;
|
||||||
if &nobs=&val then test_result='PASS';
|
if &nobs=&val then test_result='PASS';
|
||||||
%end;
|
%end;
|
||||||
|
%else %if &test=ATLEAST %then %do;
|
||||||
|
if &nobs ge &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
|
%else %if &test=ATMOST %then %do;
|
||||||
|
if &nobs le &val then test_result='PASS';
|
||||||
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
test_comments="&sysmacroname: Unsatisfied test condition - &test";
|
||||||
%end;
|
%end;
|
||||||
@@ -86,4 +115,4 @@
|
|||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds;
|
drop table &ds;
|
||||||
|
|
||||||
%mend;
|
%mend mp_assertdsobs;
|
||||||
@@ -23,11 +23,10 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/sasjs/core/issues"
|
"url": "https://github.com/sasjs/core/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/sasjs/core#readme",
|
"homepage": "https://core.sasjs.io",
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "sasjs test -t viya",
|
||||||
"docs": "sasjs doc && ./sasjs/utils/build.sh"
|
"docs": "sasjs doc && ./sasjs/utils/build.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
60
tests/base/mp_assertdsobs.test.sas
Normal file
60
tests/base/mp_assertdsobs.test.sas
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_assertdsobs.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assertdsobs.sas
|
||||||
|
@li mp_assertcolvals.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
data work.somedata;
|
||||||
|
do x=1 to 15;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.somedata,
|
||||||
|
test=ATLEAST 15,
|
||||||
|
outds=work.test_the_test
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.somedata,
|
||||||
|
test=ATMOST 15,
|
||||||
|
outds=work.test_the_test
|
||||||
|
)
|
||||||
|
|
||||||
|
data work.check;
|
||||||
|
val='PASS';
|
||||||
|
run;
|
||||||
|
%mp_assertcolvals(work.test_the_test.test_result,
|
||||||
|
checkvals=work.check.val,
|
||||||
|
desc=Testing ATLEAST / ATMOST for passes,
|
||||||
|
test=ALLVALS
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.somedata,
|
||||||
|
test=ATLEAST 16,
|
||||||
|
outds=work.test_the_test2
|
||||||
|
)
|
||||||
|
%mp_assertdsobs(work.somedata,
|
||||||
|
test=ATMOST 14,
|
||||||
|
outds=work.test_the_test2
|
||||||
|
)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
set work.test_the_test2;
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
data work.check2;
|
||||||
|
val='FAIL';
|
||||||
|
run;
|
||||||
|
%mp_assertcolvals(work.test_the_test2.test_result,
|
||||||
|
checkvals=work.check2.val,
|
||||||
|
desc=Testing ATLEAST / ATMOST for failures,
|
||||||
|
test=ALLVALS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user