testilo 7.0.5 → 7.0.7

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.
package/README.md CHANGED
@@ -107,7 +107,7 @@ Execution by a module:
107
107
 
108
108
  ```javaScript
109
109
  const {merge} = require('testilo/merge');
110
- merge('tp25', 'weborgs')
110
+ merge('tp25', 'weborgs', 'developer@w3.org')
111
111
  .then(() => {
112
112
  console.log('Merger complete');
113
113
  });
@@ -116,10 +116,10 @@ merge('tp25', 'weborgs')
116
116
  Execution by a user:
117
117
 
118
118
  ```bash
119
- node call merge tp25 weborgs
119
+ node call merge tp25 weborgs developer@w3.org
120
120
  ```
121
121
 
122
- In these examples, a copy of the script file named `tp25.json` in the `SCRIPTDIR` directory is aimed at all the hosts in the batch file named `weborgs.json` in the `BATCHDIR` directory, and the resulting host-specific scripts are saved in the `JOBDIR` directory.
122
+ In these examples, a copy of the script file named `tp25.json` in the `SCRIPTDIR` directory is aimed at all the hosts in the batch file named `weborgs.json` in the `BATCHDIR` directory, and the resulting jobs are saved in the `JOBDIR` directory. Each job has a `sources` property that identifies an email address to be notified after the job has been run.
123
123
 
124
124
  ### `score`
125
125
 
package/aim.js CHANGED
@@ -1,6 +1,11 @@
1
1
  /*
2
2
  aim.js
3
3
  Module for aiming a script at a host.
4
+ Arguments:
5
+ 0. script object.
6
+ 1. host object.
7
+ 2. email address to be notified of completion.
8
+ 3?. time stamp.
4
9
  */
5
10
 
6
11
  // ########## FUNCTIONS
@@ -8,7 +13,7 @@
8
13
  // Returns a string representing the date and time.
9
14
  const nowString = () => (new Date()).toISOString().slice(0, 19);
10
15
  // Returns a script, aimed at a host, as a job.
11
- exports.aim = (script, host, requester) => {
16
+ exports.aim = (script, host, requester, timeStamp = '') => {
12
17
  // Initialize a job based on the script.
13
18
  const job = JSON.parse(JSON.stringify(script));
14
19
  // Make all url commands in the script visit the host.
@@ -22,11 +27,13 @@ exports.aim = (script, host, requester) => {
22
27
  // Add source information to the script.
23
28
  job.sources = {
24
29
  script: script.id,
30
+ batch: '',
25
31
  host,
26
32
  requester
27
33
  }
28
- // Create a job-creation time stamp.
29
- const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
34
+ // Create a job-creation time stamp, if not specified.
35
+
36
+ timeStamp = timeStamp || Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
30
37
  // Change the script ID to a job ID.
31
38
  job.id = `${timeStamp}-${script.id}-${host.id}`;
32
39
  // Add the job-creation time to the script.
package/call.js CHANGED
@@ -71,8 +71,8 @@ const callAim = async (scriptName, hostURL, hostName, hostID, requester) => {
71
71
  console.log(`Script ${scriptID} aimed at ${hostName} saved as job ${jobID}.json in ${jobDir}`);
72
72
  };
73
73
  // Fulfills a merger request.
74
- const callMerge = async (scriptName, batchName) => {
75
- await merge(scriptName, batchName);
74
+ const callMerge = async (scriptName, batchName, requester) => {
75
+ await merge(scriptName, batchName, requester);
76
76
  console.log(`Batch ${batchName}.json merged into script ${scriptName} in ${jobDir}`);
77
77
  };
78
78
  // Fulfills a scoring request.
@@ -117,34 +117,12 @@ const callScore = async (scoreProcID, reportIDStart = '') => {
117
117
  };
118
118
  // Fulfills a multiple-report scoring request.
119
119
  const callMultiScore = async scoreProcID => {
120
- // Identify all the raw reports.
121
- const rawFileNames = await fs.readdir(rawDir);
122
- const rawReportNames = rawFileNames.filter(fileName => fileName.endsWith('.json'));
123
- // If any exist:
124
- if (rawReportNames.length) {
125
- // For each of them:
126
- const {scorer} = require(`${scoreProcDir}/${scoreProcID}.js`);
127
- for (const rawReportName of rawReportNames) {
128
- // Score it.
129
- const rawReportJSON = await fs.readFile(`${rawDir}/${rawReportName}.json`);
130
- const rawReport = JSON.parse(rawReportJSON);
131
- const scoredReport = score(scorer, rawReport);
132
- // Save it, scored.
133
- await fs.writeFile(
134
- `${scoredDir}/${scoredReport.id}.json`, JSON.stringify(scoredReport, null, 2)
135
- );
136
- console.log(`Report ${rawReport.id} scored and saved in ${scoredDir}`);
137
- }
138
- }
139
- // Otherwise, i.e. if no raw report exists:
140
- else {
141
- // Report this.
142
- console.log('ERROR: No raw report found');
143
- }
120
+ // Score all raw reports.
121
+ await multiScore(scoreProcID);
144
122
  };
145
123
  // Prepares to fulfill a digesting request.
146
124
  const digestPrep = async digestProcID => {
147
- const {digest} = require('testilo/digest');
125
+ const {digest} = require('./digest');
148
126
  const {makeQuery} = require(`${digestProcDir}/${digestProcID}/index`);
149
127
  const digestTemplate = await fs.readFile(`${digestProcDir}/${digestProcID}/index.html`, 'utf8');
150
128
  // Identify the scored reports.
@@ -162,12 +140,12 @@ const digestPrep = async digestProcID => {
162
140
  // Digests and saves a report.
163
141
  const digestReport = async (scoredReportName, prepData) => {
164
142
  // Digest the specified report.
165
- const scoredReportJSON = await fs.readFile(`${scoredDir}/${scoredReportName}.json`, 'utf8');
143
+ const scoredReportJSON = await fs.readFile(`${scoredDir}/${scoredReportName}`, 'utf8');
166
144
  const scoredReport = JSON.parse(scoredReportJSON);
167
145
  const digestedReport = digest(prepData.digestTemplate, prepData.makeQuery, scoredReport);
168
146
  // Save it, digested.
169
- await fs.writeFile(`${digestedDir}/${digestedReport.id}.html`, digestedReport);
170
- console.log(`Report ${scoredReport.id} digested and saved in ${digestedDir}`);
147
+ await fs.writeFile(`${digestedDir}/${scoredReport.job.id}.html`, digestedReport);
148
+ console.log(`Digested report ${scoredReport.job.id} saved in ${digestedDir}`);
171
149
  };
172
150
  // Fulfills a digesting request.
173
151
  const callDigest = async (digestProcID, reportIDStart = '') => {
@@ -218,14 +196,14 @@ const callMultiDigest = async digestProcID => {
218
196
  console.log('ERROR: No raw report found');
219
197
  }
220
198
  console.log(
221
- `Digesting completed. Digest proc: ${digestProcID}. Report count: ${prepData.scoredReportNames.length}. Directory: ${digestedDir}`
199
+ `Digesting completed. Digest proc: ${digestProcID}. Report count: ${prepData.scoredReportNames.length}. Directory: ${digestedDir}.`
222
200
  );
223
201
  };
224
202
  // Fulfills a comparison request.
225
203
  const callCompare = async (compareProcID, comparisonNameBase) => {
226
204
  await compare(compareProcID, comparisonNameBase);
227
205
  console.log(
228
- `Comparison completed. Comparison proc: ${compareProcID}. Directory: ${comparisonDir}`
206
+ `Comparison completed. Comparison proc: ${compareProcID}. Directory: ${comparisonDir}.`
229
207
  );
230
208
  };
231
209
 
@@ -238,7 +216,7 @@ if (fn === 'aim' && fnArgs.length === 5) {
238
216
  console.log('Execution completed');
239
217
  });
240
218
  }
241
- else if (fn === 'merge' && fnArgs.length === 2) {
219
+ else if (fn === 'merge' && fnArgs.length === 3) {
242
220
  callMerge(... fnArgs)
243
221
  .then(() => {
244
222
  console.log('Execution completed');
package/digest.js CHANGED
@@ -20,6 +20,6 @@ exports.digest = (digestTemplate, digestProc, scoredReport) => {
20
20
  // Use it to replace the placeholders in the template.
21
21
  const digest = replaceHolders(digestTemplate, query);
22
22
  // Return the digest.
23
- console.log(`Report ${scoredReport.id} digested`);
23
+ console.log(`Report ${scoredReport.job.id} digested`);
24
24
  return digest;
25
25
  };
package/merge.js CHANGED
@@ -1,12 +1,13 @@
1
1
  /*
2
2
  merge.js
3
- Merges a batch and a script to produce host-specific scripts.
3
+ Merges a batch and a script to produce jobs.
4
4
  Arguments:
5
5
  0. base of name of script located in process.env.SCRIPTDIR.
6
6
  1. base of name of batch located in process.env.BATCHDIR.
7
+ 2. email address to be notified of completion.
7
8
  Usage example:
8
- node merge tp18 weborgs
9
- Note: The subdirectory for host-specific scripts will be created if it does not exist.
9
+ node merge tp25 weborgs developer@w3.org
10
+ Note: The subdirectory for jobs will be created if it does not exist.
10
11
  */
11
12
 
12
13
  // ########## IMPORTS
@@ -15,6 +16,8 @@
15
16
  require('dotenv').config();
16
17
  // Module to read and write files.
17
18
  const fs = require('fs/promises');
19
+ // Module to aim a script at a host.
20
+ const {aim} = require('./aim');
18
21
 
19
22
  // ########## CONSTANTS
20
23
 
@@ -24,46 +27,25 @@ const jobDir = process.env.JOBDIR || 'watch';
24
27
 
25
28
  // ########## FUNCTIONS
26
29
 
27
- // Returns a string representing the date and time.
28
- const nowString = () => (new Date()).toISOString().slice(0, 19);
29
- // Merges a batch into a script and writes host-specific scripts.
30
- exports.merge = async (scriptName, batchName) => {
30
+ // Merges a batch into a script and writes jobs.
31
+ exports.merge = async (scriptName, batchName, requester) => {
32
+ // Get the script and the batch.
31
33
  const scriptJSON = await fs.readFile(`${scriptDir}/${scriptName}.json`, 'utf8');
32
34
  const batchJSON = await fs.readFile(`${batchDir}/${batchName}.json`, 'utf8');
33
35
  const script = JSON.parse(scriptJSON);
34
36
  const batch = JSON.parse(batchJSON);
35
- // Create the watch directory if it does not exist.
36
- await fs.mkdir(jobDir, {recursive: true});
37
- // Create a job-creation time stamp.
38
37
  const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
38
+ // Create the job directory if it does not exist.
39
+ await fs.mkdir(jobDir, {recursive: true});
39
40
  // For each host in the batch:
40
41
  const {hosts} = batch;
41
- const newScripts = hosts.map(host => {
42
- // Copy the script.
43
- const newScript = JSON.parse(JSON.stringify(script));
44
- // In the copy, make all url commands visit the host.
45
- newScript.commands.forEach(command => {
46
- if (command.type === 'url') {
47
- command.id = host.id;
48
- command.which = host.which;
49
- command.what = host.what;
50
- }
51
- });
52
- // Add source information to the script.
53
- newScript.sources = {
54
- script: script.id,
55
- batch: batch.id
56
- }
57
- // Add the job-creation time to the script.
58
- newScript.jobCreationTime = nowString();
59
- // Change the script ID to a job ID.
60
- newScript.id = `${timeStamp}-${newScript.id}-${host.id}`;
61
- // Return the host-specific script.
62
- return newScript;
63
- });
64
- // Write the host-specific scripts.
65
- for (const newScript of newScripts) {
66
- await fs.writeFile(`${jobDir}/${newScript.id}.json`, JSON.stringify(newScript, null, 2));
42
+ for (const host of hosts) {
43
+ // Aim the script at the host.
44
+ const job = await aim(script, host, requester, timeStamp);
45
+ // Add the batch name to the job.
46
+ job.sources.batch = batchName;
47
+ // Save the job.
48
+ await fs.writeFile(`${jobDir}/${job.id}.json`, JSON.stringify(job, null, 2));
67
49
  };
68
- console.log(`Merger completed. Script count: ${hosts.length}. Time stamp: ${timeStamp}`);
50
+ console.log(`Merger completed. Job count: ${hosts.length}. Time stamp ${timeStamp}.`);
69
51
  };
package/multiScore.js CHANGED
@@ -14,6 +14,8 @@
14
14
  require('dotenv').config();
15
15
  // Module to read and write files.
16
16
  const fs = require('fs/promises');
17
+ // Module to score reports.
18
+ const {score} = require('./score');
17
19
 
18
20
  // ########## CONSTANTS
19
21
 
@@ -25,21 +27,22 @@ const scoreProcDir = process.env.SCOREPROCDIR || `${__dirname}/procs/score`;
25
27
 
26
28
  // Score the specified reports and return their count.
27
29
  exports.multiScore = async scoreProcID => {
30
+ // Get the score proc.
31
+ const {scorer} = require(`${scoreProcDir}/${scoreProcID}`);
28
32
  // Identify the reports to be scored.
29
33
  let reportFileNames = await fs.readdir(reportDirRaw);
30
34
  reportFileNames = reportFileNames.filter(fileName => fileName.endsWith('.json'));
31
35
  // For each of them:
32
- const {scorer} = require(`${scoreProcDir}/${scoreProcID}`);
33
36
  for (const fileName of reportFileNames) {
34
37
  // Score it.
35
- const reportJSON = await fs.readFile(`${reportDirRaw}/${fileName}`, 'utf8');
36
- const report = JSON.parse(reportJSON);
37
- await scorer(report);
38
- report.scoreProcID = scoreProcID;
38
+ const rawReportJSON = await fs.readFile(`${reportDirRaw}/${fileName}`, 'utf8');
39
+ const rawReport = JSON.parse(rawReportJSON);
40
+ const scoredReport = await score(scorer, rawReport);
39
41
  // Write it to a file.
40
- const scoredReportJSON = JSON.stringify(report, null, 2);
42
+ const scoredReportJSON = JSON.stringify(scoredReport, null, 2);
41
43
  await fs.writeFile(`${reportDirScored}/${fileName}`, `${scoredReportJSON}\n`);
42
- console.log(`Report ${fileName.slice(0, -5)} scored and saved`);
43
44
  };
44
- return reportFileNames.length;
45
+ console.log(
46
+ `Scored reports saved in ${reportDirScored}. Report count: ${reportFileNames.length}.`
47
+ );
45
48
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "7.0.5",
3
+ "version": "7.0.7",
4
4
  "description": "Client that scores and digests Testaro reports",
5
5
  "main": "aim.js",
6
6
  "scripts": {
package/score.js CHANGED
@@ -9,11 +9,11 @@
9
9
  // ########## FUNCTIONS
10
10
 
11
11
  // Score the specified raw report and return it, scored.
12
- exports.score = async (scoreProc, rawReport) => {
12
+ exports.score = async (scorer, rawReport) => {
13
13
  // Initialize a scored report.
14
14
  const scoredReport = JSON.parse(JSON.stringify(rawReport));
15
15
  // Score it.
16
- await scoreProc(scoredReport);
16
+ await scorer(scoredReport);
17
17
  console.log(`Report ${rawReport.job.id} scored`);
18
18
  return scoredReport;
19
19
  };