@jrpool/kilotest 59.0.2 → 59.1.0
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 +2 -2
- package/api/orderNewTest.ts +1 -1
- package/api/orderRetest.ts +1 -1
- package/api/util.ts +1 -1
- package/capability.md +1 -1
- package/docs/AI-TOOLS.md +1 -1
- package/env.example +1 -1
- package/index.ts +5 -2
- package/lhm.plugin.json +25 -25
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/mcp.test.ts +4 -4
- package/mcp.ts +31 -35
- package/openapi.yaml +2 -2
- package/package.json +1 -1
- package/scripts/generate-openapi.ts +1 -1
- package/server.json +2 -2
- package/test/dbFixture.ts +1 -0
- package/test/fixtures/buildFixtures.ts +1 -0
- package/util.test.ts +176 -2
- package/util.ts +74 -29
- package/web/home/index.html +4 -4
- package/web/listIssues/index.html +1 -1
- package/web/listIssues/index.ts +45 -24
- package/web/listIssues/listIssues.test.ts +3 -3
- package/web/listPages/listPages.test.ts +3 -3
- package/web/listTopIssues/listTopIssues.test.ts +37 -5
- package/web/reannotate/reannotate.test.ts +2 -2
- package/web/reannotateForm/reannotateForm.test.ts +37 -6
|
@@ -5,12 +5,31 @@
|
|
|
5
5
|
|
|
6
6
|
// IMPORTS
|
|
7
7
|
|
|
8
|
-
import {test, before, after} from 'node:test';
|
|
8
|
+
import {test, before, after, mock} from 'node:test';
|
|
9
9
|
import assert from 'node:assert/strict';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import fs from 'node:fs/promises';
|
|
12
12
|
import {parse} from 'node-html-parser';
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
// Mock the util functions called by index.ts before importing it, so that
|
|
15
|
+
// it imports the mocked versions. Other exports delegate to the real module.
|
|
16
|
+
import * as realUtil from '../../util.ts';
|
|
17
|
+
let getReportCallCount = 0;
|
|
18
|
+
let failGetReportOnCall = -1;
|
|
19
|
+
mock.module('../../util.ts', {
|
|
20
|
+
exports: {
|
|
21
|
+
...realUtil,
|
|
22
|
+
getReport: async (...args: any[]) => {
|
|
23
|
+
getReportCallCount++;
|
|
24
|
+
if (getReportCallCount === failGetReportOnCall) {
|
|
25
|
+
return {error: 'Report is invalid (test override)'};
|
|
26
|
+
}
|
|
27
|
+
return (realUtil.getReport as any)(...args);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} as any);
|
|
31
|
+
|
|
32
|
+
const {answer} = await import('./index.ts') as any;
|
|
14
33
|
|
|
15
34
|
// SETUP AND TEARDOWN
|
|
16
35
|
|
|
@@ -54,23 +73,36 @@ test('listTopIssues excludes cantTell instances from issue counts', async () =>
|
|
|
54
73
|
assert.ok(!result.answerPage.includes('focus indication poor'));
|
|
55
74
|
});
|
|
56
75
|
|
|
57
|
-
test('listTopIssues
|
|
76
|
+
test('listTopIssues omits a report that is not usable', async () => {
|
|
58
77
|
const dbDir = (await import('../../test/dbFixture.ts')).fixtureDBDir;
|
|
59
78
|
const reportsDir = path.join(dbDir, 'reports');
|
|
60
79
|
const invalidReportPath = path.join(reportsDir, '260101T9999-bad.json');
|
|
61
80
|
try {
|
|
62
|
-
//
|
|
81
|
+
// Not usable by isUsableReport (no acts or catalog), so it produces no extract
|
|
82
|
+
// and contributes nothing to the summary.
|
|
63
83
|
const invalidReport = {
|
|
64
84
|
target: {what: 'Invalid TopIssues Report', url: 'https://example.com/invalidtop'},
|
|
65
85
|
jobData: {endTime: '26-01-01T00:10'}
|
|
66
86
|
};
|
|
67
87
|
await fs.writeFile(invalidReportPath, JSON.stringify(invalidReport, null, 2));
|
|
88
|
+
const result: any = await answer();
|
|
89
|
+
assert.equal(result.status, 'ok');
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await fs.unlink(invalidReportPath).catch(() => {});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('listTopIssues returns an error when a report read fails', async () => {
|
|
97
|
+
getReportCallCount = 0;
|
|
98
|
+
failGetReportOnCall = 1;
|
|
99
|
+
try {
|
|
68
100
|
const result: any = await answer();
|
|
69
101
|
assert.equal(result.status, 'error');
|
|
70
102
|
assert.ok(result.message);
|
|
71
103
|
}
|
|
72
104
|
finally {
|
|
73
|
-
|
|
105
|
+
failGetReportOnCall = -1;
|
|
74
106
|
}
|
|
75
107
|
});
|
|
76
108
|
|
|
@@ -90,8 +90,8 @@ test('answer returns an error when a report fails annotation', {timeout: 2000},
|
|
|
90
90
|
// Back up all fixture reports, because reannotation modifies good reports
|
|
91
91
|
// in place before it reaches the bad one and returns an error.
|
|
92
92
|
const backups = await backupReports();
|
|
93
|
-
// Create a temporary report file that
|
|
94
|
-
//
|
|
93
|
+
// Create a temporary report file that fails getReport validation
|
|
94
|
+
// (acts is not an array). It is too fresh to be quarantined, so it stays put.
|
|
95
95
|
const badReportName = '990101T0000-bad.json';
|
|
96
96
|
const badReportPath = path.join(reportsDir, badReportName);
|
|
97
97
|
const badReport = {
|
|
@@ -6,13 +6,31 @@
|
|
|
6
6
|
|
|
7
7
|
// IMPORTS
|
|
8
8
|
|
|
9
|
-
import {test, before, after, beforeEach} from 'node:test';
|
|
9
|
+
import {test, before, after, beforeEach, mock} from 'node:test';
|
|
10
10
|
import assert from 'node:assert/strict';
|
|
11
11
|
import fs from 'node:fs/promises';
|
|
12
12
|
import os from 'node:os';
|
|
13
13
|
import path from 'node:path';
|
|
14
14
|
import {parse} from 'node-html-parser';
|
|
15
15
|
|
|
16
|
+
// Mock the util functions called by index.ts before it is ever imported, so that
|
|
17
|
+
// it imports the mocked versions. Other exports delegate to the real module.
|
|
18
|
+
import * as realUtil from '../../util.ts';
|
|
19
|
+
let getReportCallCount = 0;
|
|
20
|
+
let failGetReportOnCall = -1;
|
|
21
|
+
mock.module('../../util.ts', {
|
|
22
|
+
exports: {
|
|
23
|
+
...realUtil,
|
|
24
|
+
getReport: async (...args: any[]) => {
|
|
25
|
+
getReportCallCount++;
|
|
26
|
+
if (getReportCallCount === failGetReportOnCall) {
|
|
27
|
+
return {error: 'Report is invalid (test override)'};
|
|
28
|
+
}
|
|
29
|
+
return (realUtil.getReport as any)(...args);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} as any);
|
|
33
|
+
|
|
16
34
|
// CONSTANTS
|
|
17
35
|
|
|
18
36
|
import {fixtureDBDir} from '../../test/dbFixture.ts';
|
|
@@ -101,9 +119,9 @@ test('answer returns ok with no-reclassified message when reports have no violat
|
|
|
101
119
|
}
|
|
102
120
|
});
|
|
103
121
|
|
|
104
|
-
test('answer
|
|
105
|
-
//
|
|
106
|
-
//
|
|
122
|
+
test('answer ignores a report that is not usable', async () => {
|
|
123
|
+
// A report that fails getReport validation (acts is not an array) produces no
|
|
124
|
+
// extract, so it is ignored rather than causing an error.
|
|
107
125
|
const badReportName = '990101T0000-bad.json';
|
|
108
126
|
const badReportPath = path.join(reportsDir, badReportName);
|
|
109
127
|
const badReport = {
|
|
@@ -117,8 +135,7 @@ test('answer returns an error when a report fails to load', async () => {
|
|
|
117
135
|
try {
|
|
118
136
|
const {answer} = await import('./index.ts');
|
|
119
137
|
const result = await answer();
|
|
120
|
-
assert.equal(result.status, '
|
|
121
|
-
assert.ok(result.message.includes('not usable'), `Expected message about unusable report, got: ${result.message}`);
|
|
138
|
+
assert.equal(result.status, 'ok');
|
|
122
139
|
}
|
|
123
140
|
finally {
|
|
124
141
|
try {
|
|
@@ -129,3 +146,17 @@ test('answer returns an error when a report fails to load', async () => {
|
|
|
129
146
|
}
|
|
130
147
|
}
|
|
131
148
|
});
|
|
149
|
+
|
|
150
|
+
test('answer returns an error when a report read fails', async () => {
|
|
151
|
+
getReportCallCount = 0;
|
|
152
|
+
failGetReportOnCall = 1;
|
|
153
|
+
try {
|
|
154
|
+
const {answer} = await import('./index.ts');
|
|
155
|
+
const result = await answer();
|
|
156
|
+
assert.equal(result.status, 'error');
|
|
157
|
+
assert.ok(result.message);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
failGetReportOnCall = -1;
|
|
161
|
+
}
|
|
162
|
+
});
|