testilo 41.7.0 → 42.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +46 -7
  2. package/call.js +36 -0
  3. package/issues.js +46 -0
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -359,7 +359,7 @@ The second form will create a script that prescribes tests for all the rules of
359
359
 
360
360
  The third form will create a script that prescribes tests for all the rules classified by the named issue-classification file into any of the specified issues.
361
361
 
362
- In this statement, replace `id` with an ID for the script, such as `headings1`, consisting of ASCII alphanumeric characters, or with `''` if you want Testilo to create an ID. Replace `what` with a string describing the script, or with `''` if you want Testilo to create a generic description. Replace `device` with a valid device ID.
362
+ In this statement, replace `id` with an ID for the script, such as `headings1`, consisting of ASCII alphanumeric characters, or with `''` if you want Testilo to create an ID. Replace `what` with a string describing the script, or with `''` if you want Testilo to create a generic description. Replace `deviceID` with a valid device ID.
363
363
 
364
364
  The `call` module will retrieve the named classification, if any.
365
365
  The `script` module will create a script.
@@ -914,13 +914,15 @@ When a user invokes `track()` in this example, the `call` module:
914
914
 
915
915
  The tracking reports created by `track()` are HTML files, and they expect a `style.css` file to exist in their directory. The `reports/tracking/style.css` file in Testilo is an appropriate stylesheet to be copied into the directory where tracking reports are written.
916
916
 
917
- ### Tool crediting
917
+ ### Statistics
918
918
 
919
- If you use Testaro to perform all the tests of all the tools on multiple targets and score the reports with a score proc that maps tool rules onto tool-agnostic issues, you may want to tabulate the comparative efficacy of each tool in discovering instances of issues. Testilo can help you do this by producing a _credit report_.
919
+ If you use Testaro to perform all the tests of all the tools on multiple targets and score the reports with a score proc that maps tool rules onto tool-agnostic issues, you may want to get statistics on tools and issues, aggregated from the scored reports. Testilo has two procs for this purpose.
920
+
921
+ #### Tool crediting
920
922
 
921
923
  The `credit` module tabulates the contribution of each tool to the discovery of issue instances in a collection of scored reports. Its `credit()` function takes two arguments: a report description and an array of `score` properties of scored reports.
922
924
 
923
- The credit report contains four sections:
925
+ The function produces a credit report containing four sections:
924
926
  - `counts`: for each issue, how many instances each tool reported
925
927
  - `onlies`: for each issue of which only 1 tool reported instances, which tool it was
926
928
  - `mosts`: for each issue of which at least 2 tools reported instances, which tool(s) reported the maximum instance count
@@ -928,11 +930,11 @@ The credit report contains four sections:
928
930
  - `onlies`: a list of the issues that only the tool reported instances of
929
931
  - `mosts`: a list of the issues for which the instance count of the tool was not surpassed by that of any other tool
930
932
 
931
- #### Invocation
933
+ ##### Invocation
932
934
 
933
935
  There are two ways to use the `credit` module.
934
936
 
935
- ##### By a module
937
+ ###### By a module
936
938
 
937
939
  A module can invoke `credit()` in this way:
938
940
 
@@ -944,7 +946,7 @@ const creditReport = credit('June 2025', reportScores);
944
946
 
945
947
  The first argument to `credit()` is a description to be included in the credit report. The second argument is an array of `score` properties of scored report objects. The `credit()` function returns a credit report. The invoking module can further dispose of the credit report as needed.
946
948
 
947
- ##### By a user
949
+ ###### By a user
948
950
 
949
951
  A user can invoke `credit()` in one of these ways:
950
952
 
@@ -959,6 +961,43 @@ When a user invokes `credit` in this example, the `call` module:
959
961
  - creates an ID for the credit report.
960
962
  - writes the credit report as a JSON file, with the ID as the base of its file name and `legislators` as its description, to the `credit` subdirectory of the `REPORTDIR` directory.
961
963
 
964
+ ### Issue scores
965
+
966
+ The `issues` module tabulates total issue scores. Its `issues()` function takes two arguments: a report description and an array of `score` properties of scored reports.
967
+
968
+ The function produces an issue report, an object with issue properties, whose values are the totals of the scores of the respective issues.
969
+
970
+ ##### Invocation
971
+
972
+ There are two ways to use the `credit` module.
973
+
974
+ ###### By a module
975
+
976
+ A module can invoke `issues()` in this way:
977
+
978
+ ```javaScript
979
+ const {issues} = require('testilo/issues');
980
+ const reportScores = […];
981
+ const issuesReport = issues('legislators', reportScores);
982
+ ```
983
+
984
+ The arguments to `issues()` are a report description and an array of `score` properties of scored report objects. The `issues()` function returns an issues report. The invoking module can further dispose of the issues report as needed.
985
+
986
+ ###### By a user
987
+
988
+ A user can invoke `issues()` in one of these ways:
989
+
990
+ ```bash
991
+ node call issues legislators
992
+ node call issues legislators 241106
993
+ ```
994
+
995
+ When a user invokes `issues` in this example, the `call` module:
996
+ - gets all reports, or if the third argument to `call()` exists all reports whose file names begin with `'241106'`, in the `scored` subdirectory of the `REPORTDIR` directory.
997
+ - gets the `score` properties of those reports.
998
+ - creates an ID for the issues report.
999
+ - writes the issues report as a JSON file, with the ID as the base of its file name and `legislators` as its description, to the `issues` subdirectory of the `REPORTDIR` directory.
1000
+
962
1001
  ## Origin
963
1002
 
964
1003
  Work on the functionalities of Testaro and Testilo began in 2017. It was named [Autotest](https://github.com/jrpool/autotest) in early 2021 and then partitioned into the more single-purpose packages Testaro and Testilo in January 2022.
package/call.js CHANGED
@@ -60,6 +60,8 @@ const {difgest} = require('./difgest');
60
60
  const {compare} = require('./compare');
61
61
  // Function to credit tools for issues in reports.
62
62
  const {credit} = require('./credit');
63
+ // Function to credit tools for issues in reports.
64
+ const {issues} = require('./issues');
63
65
  // Function to summarize reports.
64
66
  const {summarize} = require('./summarize');
65
67
  // Function to track results.
@@ -482,6 +484,34 @@ const callCredit = async (what, selector = '') => {
482
484
  console.log('ERROR: No scored reports to be credited');
483
485
  }
484
486
  };
487
+ // Fulfills an issues request.
488
+ const callIssues = async (what, selector = '') => {
489
+ // Get the IDs of the scored reports to be analyzed.
490
+ const reportIDs = await getReportIDs('scored', selector);
491
+ // If any exist:
492
+ if (reportIDs.length) {
493
+ // Get an array of the score properties of the reports to be credited.
494
+ const reportScores = [];
495
+ for (const id of reportIDs) {
496
+ const report = await getReport('scored', id);
497
+ reportScores.push(report.score);
498
+ }
499
+ // Analyze the reports.
500
+ const reportObj = issues(what, reportScores);
501
+ // Save the issues report.
502
+ const issuesDir = `${reportDir}/issues`;
503
+ await fs.mkdir(issuesDir, {recursive: true});
504
+ const issuesReportID = getFileID(2);
505
+ const reportPath = `${issuesDir}/${issuesReportID}.json`;
506
+ await fs.writeFile(reportPath, `${JSON.stringify(reportObj, null, 2)}\n`);
507
+ console.log(`Issue scores tallied and issues report saved as ${reportPath}`);
508
+ }
509
+ // Otherwise, i.e. if no scored reports are to be analyzed:
510
+ else {
511
+ // Report this.
512
+ console.log('ERROR: No scored reports to be analyzed');
513
+ }
514
+ };
485
515
 
486
516
  // ########## OPERATION
487
517
 
@@ -558,6 +588,12 @@ else if (fn === 'credit' && fnArgs.length > 0 && fnArgs.length < 3) {
558
588
  console.log('Execution completed');
559
589
  });
560
590
  }
591
+ else if (fn === 'issues' && fnArgs.length > 0 && fnArgs.length < 3) {
592
+ callIssues(... fnArgs)
593
+ .then(() => {
594
+ console.log('Execution completed');
595
+ });
596
+ }
561
597
  else {
562
598
  console.log('ERROR: Invalid statement');
563
599
  }
package/issues.js ADDED
@@ -0,0 +1,46 @@
1
+ /*
2
+ © 2024 CVS Health and/or one of its affiliates. All rights reserved.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
21
+ */
22
+
23
+ /*
24
+ issues.js
25
+ Analyzes issue scores in an array of score properties of scored reports.
26
+ */
27
+
28
+ // Returns a tabulation of the total scores of issues reported by tools in scored reports.
29
+ exports.issues = (what, reportScores) => {
30
+ const tally = {};
31
+ reportScores.forEach(reportScore => {
32
+ Object.keys(reportScore.details.issue).forEach(issueName => {
33
+ tally[issueName] ??= 0;
34
+ tally[issueName] += reportScore.details.issue[issueName].score;
35
+ });
36
+ });
37
+ const scores = [];
38
+ Object.keys(tally).forEach(issueName => {
39
+ scores.push([issueName, tally[issueName]]);
40
+ });
41
+ scores.sort((a, b) => b[1] - a[1]);
42
+ return {
43
+ what,
44
+ scores
45
+ };
46
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "41.7.0",
3
+ "version": "42.0.1",
4
4
  "description": "Prepares Testaro jobs and processes Testaro reports",
5
5
  "main": "call.js",
6
6
  "scripts": {