doc-detective 3.5.0-dev.0 → 3.5.0-dev.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.
- package/.github/FUNDING.yml +14 -14
- package/.github/dependabot.yml +11 -11
- package/.github/workflows/auto-dev-release.yml +173 -173
- package/.github/workflows/npm-test.yaml +95 -96
- package/.github/workflows/update-core.yaml +131 -131
- package/CONTRIBUTIONS.md +27 -27
- package/LICENSE +661 -661
- package/README.md +110 -110
- package/dev/dev.config.json +3 -8
- package/dev/dev.spec.json +30 -30
- package/dev/index.js +5 -5
- package/package.json +47 -47
- package/reference.png +0 -0
- package/samples/.doc-detective.json +94 -94
- package/samples/doc-content-detect.md +10 -10
- package/samples/doc-content-inline-tests.md +23 -23
- package/samples/docker-hello.spec.json +15 -15
- package/samples/env +2 -2
- package/samples/http.spec.yaml +37 -37
- package/samples/kitten-search-detect.md +7 -7
- package/samples/kitten-search-inline.md +15 -15
- package/samples/kitten-search.spec.json +28 -28
- package/samples/local-gui.md +5 -5
- package/samples/tests.spec.json +70 -70
- package/samples/variables.env +4 -4
- package/scripts/bump-sync-version-core.js +108 -110
- package/src/checkDependencies.js +84 -84
- package/src/index.js +72 -72
- package/src/utils.js +1023 -1023
- package/test/artifacts/cleanup.spec.json +18 -18
- package/test/artifacts/config.json +6 -6
- package/test/artifacts/doc-content.md +23 -23
- package/test/artifacts/env +2 -2
- package/test/artifacts/httpRequest.spec.yaml +37 -37
- package/test/artifacts/runShell.spec.json +29 -29
- package/test/artifacts/setup.spec.json +18 -18
- package/test/artifacts/test.spec.json +46 -46
- package/test/resolvedTests.test.js +193 -193
- package/test/runTests.test.js +53 -53
- package/test/server/index.js +185 -185
- package/test/server/public/index.html +174 -174
- package/test/test-config.json +12 -12
- package/test/test-results.json +124 -124
- package/test/utils.test.js +634 -298
package/test/utils.test.js
CHANGED
|
@@ -1,298 +1,634 @@
|
|
|
1
|
-
const { setArgs, setConfig, outputResults } = require("../src/utils");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const fs = require("fs");
|
|
4
|
-
|
|
5
|
-
before(async function () {
|
|
6
|
-
const { expect } = await import("chai");
|
|
7
|
-
global.expect = expect;
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
describe("Util tests", function () {
|
|
11
|
-
// Test that arguments are parsed correctly
|
|
12
|
-
it("Yargs parses arguments correctly", function () {
|
|
13
|
-
const argSets = [
|
|
14
|
-
{
|
|
15
|
-
args: ["node", "runTests.js", "--input", "input.spec.json"],
|
|
16
|
-
expected: { i: "input.spec.json" },
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
args: [
|
|
20
|
-
"node",
|
|
21
|
-
"runTests.js",
|
|
22
|
-
"--input",
|
|
23
|
-
"input.spec.json",
|
|
24
|
-
"--logLevel",
|
|
25
|
-
"debug",
|
|
26
|
-
],
|
|
27
|
-
expected: { i: "input.spec.json", l: "debug" },
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
args: [
|
|
31
|
-
"node",
|
|
32
|
-
"runTests.js",
|
|
33
|
-
"--input",
|
|
34
|
-
"input.spec.json",
|
|
35
|
-
"--logLevel",
|
|
36
|
-
"debug",
|
|
37
|
-
"--config",
|
|
38
|
-
"config.json",
|
|
39
|
-
],
|
|
40
|
-
|
|
41
|
-
expected: { i: "input.spec.json", l: "debug", c: "config.json" },
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
args: [
|
|
45
|
-
"node",
|
|
46
|
-
"runTests.js",
|
|
47
|
-
"--input",
|
|
48
|
-
"input.spec.json",
|
|
49
|
-
"--output",
|
|
50
|
-
".",
|
|
51
|
-
"--logLevel",
|
|
52
|
-
"debug",
|
|
53
|
-
"--config",
|
|
54
|
-
"config.json",
|
|
55
|
-
],
|
|
56
|
-
expected: {
|
|
57
|
-
i: "input.spec.json",
|
|
58
|
-
o: ".",
|
|
59
|
-
l: "debug",
|
|
60
|
-
c: "config.json",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
args: [
|
|
65
|
-
"node",
|
|
66
|
-
"runTests.js",
|
|
67
|
-
"--input",
|
|
68
|
-
"input.spec.json",
|
|
69
|
-
"--allow-unsafe",
|
|
70
|
-
],
|
|
71
|
-
expected: {
|
|
72
|
-
i: "input.spec.json",
|
|
73
|
-
allowUnsafe: true,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
argSets.forEach((argSet) => {
|
|
78
|
-
expect(setArgs(argSet.args)).to.deep.include(argSet.expected);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Test that config overrides are set correctly
|
|
83
|
-
it("Config overrides are set correctly", async function () {
|
|
84
|
-
// This test takes a bit longer
|
|
85
|
-
this.timeout(5000);
|
|
86
|
-
|
|
87
|
-
configSets = [
|
|
88
|
-
{
|
|
89
|
-
// Input override
|
|
90
|
-
args: ["node", "runTests.js", "--input", "input.spec.json"],
|
|
91
|
-
expected: { input: [path.resolve(process.cwd(), "input.spec.json")] },
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
// Input and logLevel overrides
|
|
95
|
-
args: [
|
|
96
|
-
"node",
|
|
97
|
-
"runTests.js",
|
|
98
|
-
"--input",
|
|
99
|
-
"input.spec.json",
|
|
100
|
-
"--logLevel",
|
|
101
|
-
"debug",
|
|
102
|
-
],
|
|
103
|
-
expected: {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"
|
|
152
|
-
"
|
|
153
|
-
"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
1
|
+
const { setArgs, setConfig, outputResults } = require("../src/utils");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
before(async function () {
|
|
6
|
+
const { expect } = await import("chai");
|
|
7
|
+
global.expect = expect;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe("Util tests", function () {
|
|
11
|
+
// Test that arguments are parsed correctly
|
|
12
|
+
it("Yargs parses arguments correctly", function () {
|
|
13
|
+
const argSets = [
|
|
14
|
+
{
|
|
15
|
+
args: ["node", "runTests.js", "--input", "input.spec.json"],
|
|
16
|
+
expected: { i: "input.spec.json" },
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
args: [
|
|
20
|
+
"node",
|
|
21
|
+
"runTests.js",
|
|
22
|
+
"--input",
|
|
23
|
+
"input.spec.json",
|
|
24
|
+
"--logLevel",
|
|
25
|
+
"debug",
|
|
26
|
+
],
|
|
27
|
+
expected: { i: "input.spec.json", l: "debug" },
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
args: [
|
|
31
|
+
"node",
|
|
32
|
+
"runTests.js",
|
|
33
|
+
"--input",
|
|
34
|
+
"input.spec.json",
|
|
35
|
+
"--logLevel",
|
|
36
|
+
"debug",
|
|
37
|
+
"--config",
|
|
38
|
+
"config.json",
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
expected: { i: "input.spec.json", l: "debug", c: "config.json" },
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
args: [
|
|
45
|
+
"node",
|
|
46
|
+
"runTests.js",
|
|
47
|
+
"--input",
|
|
48
|
+
"input.spec.json",
|
|
49
|
+
"--output",
|
|
50
|
+
".",
|
|
51
|
+
"--logLevel",
|
|
52
|
+
"debug",
|
|
53
|
+
"--config",
|
|
54
|
+
"config.json",
|
|
55
|
+
],
|
|
56
|
+
expected: {
|
|
57
|
+
i: "input.spec.json",
|
|
58
|
+
o: ".",
|
|
59
|
+
l: "debug",
|
|
60
|
+
c: "config.json",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
args: [
|
|
65
|
+
"node",
|
|
66
|
+
"runTests.js",
|
|
67
|
+
"--input",
|
|
68
|
+
"input.spec.json",
|
|
69
|
+
"--allow-unsafe",
|
|
70
|
+
],
|
|
71
|
+
expected: {
|
|
72
|
+
i: "input.spec.json",
|
|
73
|
+
allowUnsafe: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
argSets.forEach((argSet) => {
|
|
78
|
+
expect(setArgs(argSet.args)).to.deep.include(argSet.expected);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Test that config overrides are set correctly
|
|
83
|
+
it("Config overrides are set correctly", async function () {
|
|
84
|
+
// This test takes a bit longer
|
|
85
|
+
this.timeout(5000);
|
|
86
|
+
|
|
87
|
+
configSets = [
|
|
88
|
+
{
|
|
89
|
+
// Input override
|
|
90
|
+
args: ["node", "runTests.js", "--input", "input.spec.json"],
|
|
91
|
+
expected: { input: [path.resolve(process.cwd(), "input.spec.json")] },
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
// Input and logLevel overrides
|
|
95
|
+
args: [
|
|
96
|
+
"node",
|
|
97
|
+
"runTests.js",
|
|
98
|
+
"--input",
|
|
99
|
+
"input.spec.json",
|
|
100
|
+
"--logLevel",
|
|
101
|
+
"debug",
|
|
102
|
+
],
|
|
103
|
+
expected: {
|
|
104
|
+
input: [path.resolve(process.cwd(), "input.spec.json")],
|
|
105
|
+
logLevel: "debug",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
// Input, logLevel, and setup overrides
|
|
110
|
+
args: [
|
|
111
|
+
"node",
|
|
112
|
+
"runTests.js",
|
|
113
|
+
"--input",
|
|
114
|
+
"input.spec.json",
|
|
115
|
+
"--logLevel",
|
|
116
|
+
"debug",
|
|
117
|
+
],
|
|
118
|
+
expected: {
|
|
119
|
+
input: [path.resolve(process.cwd(), "input.spec.json")],
|
|
120
|
+
logLevel: "debug",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
// Referenced config without overrides
|
|
125
|
+
args: ["node", "runTests.js", "--config", "./test/test-config.json"],
|
|
126
|
+
expected: {
|
|
127
|
+
input: process.cwd(),
|
|
128
|
+
logLevel: "silent",
|
|
129
|
+
recursive: true,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
// Referenced config with overrides
|
|
134
|
+
args: [
|
|
135
|
+
"node",
|
|
136
|
+
"runTests.js",
|
|
137
|
+
"--config",
|
|
138
|
+
"./test/test-config.json",
|
|
139
|
+
"--input",
|
|
140
|
+
"input.spec.json",
|
|
141
|
+
],
|
|
142
|
+
expected: {
|
|
143
|
+
input: [path.resolve(process.cwd(), "input.spec.json")],
|
|
144
|
+
logLevel: "silent",
|
|
145
|
+
recursive: true,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
// Multiple inputs
|
|
150
|
+
args: [
|
|
151
|
+
"node",
|
|
152
|
+
"runTests.js",
|
|
153
|
+
"--config",
|
|
154
|
+
"./test/test-config.json",
|
|
155
|
+
"--input",
|
|
156
|
+
"input.spec.json,anotherInput.spec.json",
|
|
157
|
+
],
|
|
158
|
+
expected: {
|
|
159
|
+
input: [
|
|
160
|
+
path.resolve(process.cwd(), "input.spec.json"),
|
|
161
|
+
path.resolve(process.cwd(), "anotherInput.spec.json"),
|
|
162
|
+
],
|
|
163
|
+
output: process.cwd(),
|
|
164
|
+
recursive: true,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
// allow-unsafe override
|
|
169
|
+
args: [
|
|
170
|
+
"node",
|
|
171
|
+
"runTests.js",
|
|
172
|
+
"--input",
|
|
173
|
+
"input.spec.json",
|
|
174
|
+
"--allow-unsafe",
|
|
175
|
+
],
|
|
176
|
+
expected: {
|
|
177
|
+
input: [path.resolve(process.cwd(), "input.spec.json")],
|
|
178
|
+
allowUnsafeSteps: true,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
// Use process.stdout.write directly to force console output during tests
|
|
184
|
+
console.log("\n===== CONFIG TEST RESULTS =====\n");
|
|
185
|
+
|
|
186
|
+
// Use Promise.all with map instead of forEach to properly handle async operations
|
|
187
|
+
await Promise.all(
|
|
188
|
+
configSets.map(async (configSet, index) => {
|
|
189
|
+
// Set config with the args
|
|
190
|
+
console.log(
|
|
191
|
+
`Config test ${index}: ${JSON.stringify(configSet, null, 2)}`
|
|
192
|
+
);
|
|
193
|
+
const configResult = await setConfig({ args: setArgs(configSet.args) });
|
|
194
|
+
console.log(
|
|
195
|
+
`Config result ${index}: ${JSON.stringify(configResult, null, 2)}\n`
|
|
196
|
+
);
|
|
197
|
+
// Deeply compare the config result with the expected result
|
|
198
|
+
deepObjectExpect(configResult, configSet.expected);
|
|
199
|
+
})
|
|
200
|
+
);
|
|
201
|
+
process.stdout.write("===== END CONFIG TEST RESULTS =====\n");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Test that results output correctly.
|
|
205
|
+
it("Results output correctly", async () => {
|
|
206
|
+
// Output test-results.json, make sure it exists, and clean it up.
|
|
207
|
+
const inputResultsPath = path.resolve("./test/test-results.json");
|
|
208
|
+
const inputResultsJSON = require(inputResultsPath);
|
|
209
|
+
const outputResultsPath = path.resolve("./test/output-test-results.json");
|
|
210
|
+
// Check that input file exists
|
|
211
|
+
expect(fs.existsSync(inputResultsPath)).to.equal(true);
|
|
212
|
+
// Output results
|
|
213
|
+
await outputResults(null, outputResultsPath, inputResultsJSON);
|
|
214
|
+
// Check that output file exists
|
|
215
|
+
expect(fs.existsSync(outputResultsPath)).to.equal(true);
|
|
216
|
+
// Clean up
|
|
217
|
+
fs.unlinkSync(outputResultsPath);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Test environment variable config detection
|
|
221
|
+
it("Config from DOC_DETECTIVE_CONFIG environment variable is loaded and merged", async function () {
|
|
222
|
+
this.timeout(5000);
|
|
223
|
+
|
|
224
|
+
// Save the original environment variable value
|
|
225
|
+
const originalEnvConfig = process.env.DOC_DETECTIVE_CONFIG;
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
// Ensure env override is not set for the default-value test
|
|
229
|
+
delete process.env.DOC_DETECTIVE_CONFIG;
|
|
230
|
+
|
|
231
|
+
// Test 1: Valid environment variable config without file config
|
|
232
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
233
|
+
logLevel: "debug",
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const config1 = await setConfig({
|
|
237
|
+
args: setArgs(["node", "runTests.js"]),
|
|
238
|
+
});
|
|
239
|
+
expect(config1.logLevel).to.equal("debug");
|
|
240
|
+
|
|
241
|
+
// Test 2: Environment variable config merged with file config (env var takes precedence)
|
|
242
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
243
|
+
logLevel: "error",
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const config2 = await setConfig({
|
|
247
|
+
configPath: "./test/test-config.json",
|
|
248
|
+
args: setArgs([
|
|
249
|
+
"node",
|
|
250
|
+
"runTests.js",
|
|
251
|
+
"--config",
|
|
252
|
+
"./test/test-config.json",
|
|
253
|
+
]),
|
|
254
|
+
});
|
|
255
|
+
// Environment variable should override file config
|
|
256
|
+
expect(config2.logLevel).to.equal("error");
|
|
257
|
+
// Check that other values from file config are preserved
|
|
258
|
+
expect(config2.telemetry.send).to.equal(false);
|
|
259
|
+
|
|
260
|
+
// Test 3: Environment variable config with command line args (args take precedence)
|
|
261
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
262
|
+
logLevel: "warning",
|
|
263
|
+
input: "env-input.json",
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const config3 = await setConfig({
|
|
267
|
+
args: setArgs([
|
|
268
|
+
"node",
|
|
269
|
+
"runTests.js",
|
|
270
|
+
"--input",
|
|
271
|
+
"cli-input.json",
|
|
272
|
+
"--logLevel",
|
|
273
|
+
"debug",
|
|
274
|
+
]),
|
|
275
|
+
});
|
|
276
|
+
// Command line args should override environment variable
|
|
277
|
+
expect(config3.logLevel).to.equal("debug");
|
|
278
|
+
expect(config3.input).to.deep.equal([
|
|
279
|
+
path.resolve(process.cwd(), "cli-input.json"),
|
|
280
|
+
]);
|
|
281
|
+
} finally {
|
|
282
|
+
// Restore the original environment variable value
|
|
283
|
+
if (originalEnvConfig !== undefined) {
|
|
284
|
+
process.env.DOC_DETECTIVE_CONFIG = originalEnvConfig;
|
|
285
|
+
} else {
|
|
286
|
+
delete process.env.DOC_DETECTIVE_CONFIG;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// Test that false values for recursive and detectSteps are preserved
|
|
292
|
+
it("Preserves false values for recursive and detectSteps config properties", async function () {
|
|
293
|
+
this.timeout(5000);
|
|
294
|
+
|
|
295
|
+
// Save original environment variable
|
|
296
|
+
const originalEnvConfig = process.env.DOC_DETECTIVE_CONFIG;
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
// Test 1: Default values when not specified (should be true)
|
|
300
|
+
const config1 = await setConfig({
|
|
301
|
+
args: setArgs(["node", "runTests.js"]),
|
|
302
|
+
});
|
|
303
|
+
expect(config1.recursive).to.equal(
|
|
304
|
+
true,
|
|
305
|
+
"recursive should default to true"
|
|
306
|
+
);
|
|
307
|
+
expect(config1.detectSteps).to.equal(
|
|
308
|
+
true,
|
|
309
|
+
"detectSteps should default to true"
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
// Test 2: Explicitly set to false in environment variable
|
|
313
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
314
|
+
recursive: false,
|
|
315
|
+
detectSteps: false,
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const config2 = await setConfig({
|
|
319
|
+
args: setArgs(["node", "runTests.js"]),
|
|
320
|
+
});
|
|
321
|
+
expect(config2.recursive).to.equal(
|
|
322
|
+
false,
|
|
323
|
+
"recursive should be false from env var"
|
|
324
|
+
);
|
|
325
|
+
expect(config2.detectSteps).to.equal(
|
|
326
|
+
false,
|
|
327
|
+
"detectSteps should be false from env var"
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
// Test 3: Explicitly set to true in environment variable
|
|
331
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
332
|
+
recursive: true,
|
|
333
|
+
detectSteps: true,
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const config3 = await setConfig({
|
|
337
|
+
args: setArgs(["node", "runTests.js"]),
|
|
338
|
+
});
|
|
339
|
+
expect(config3.recursive).to.equal(
|
|
340
|
+
true,
|
|
341
|
+
"recursive should be true from env var"
|
|
342
|
+
);
|
|
343
|
+
expect(config3.detectSteps).to.equal(
|
|
344
|
+
true,
|
|
345
|
+
"detectSteps should be true from env var"
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
// Test 4: Only one set to false
|
|
349
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
350
|
+
recursive: false,
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const config4 = await setConfig({
|
|
354
|
+
args: setArgs(["node", "runTests.js"]),
|
|
355
|
+
});
|
|
356
|
+
expect(config4.recursive).to.equal(
|
|
357
|
+
false,
|
|
358
|
+
"recursive should be false from env var"
|
|
359
|
+
);
|
|
360
|
+
expect(config4.detectSteps).to.equal(
|
|
361
|
+
true,
|
|
362
|
+
"detectSteps should default to true"
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
// Test 5: Only detectSteps set to false
|
|
366
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
367
|
+
detectSteps: false,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const config5 = await setConfig({
|
|
371
|
+
args: setArgs(["node", "runTests.js"]),
|
|
372
|
+
});
|
|
373
|
+
expect(config5.recursive).to.equal(
|
|
374
|
+
true,
|
|
375
|
+
"recursive should default to true"
|
|
376
|
+
);
|
|
377
|
+
expect(config5.detectSteps).to.equal(
|
|
378
|
+
false,
|
|
379
|
+
"detectSteps should be false from env var"
|
|
380
|
+
);
|
|
381
|
+
} finally {
|
|
382
|
+
// Restore the original environment variable value
|
|
383
|
+
if (originalEnvConfig !== undefined) {
|
|
384
|
+
process.env.DOC_DETECTIVE_CONFIG = originalEnvConfig;
|
|
385
|
+
} else {
|
|
386
|
+
delete process.env.DOC_DETECTIVE_CONFIG;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Test that false values from config file are preserved
|
|
392
|
+
it("Preserves false values for recursive and detectSteps from config file", async function () {
|
|
393
|
+
this.timeout(5000);
|
|
394
|
+
|
|
395
|
+
const testConfigDir = path.resolve("./test");
|
|
396
|
+
|
|
397
|
+
// Create temporary config files for testing
|
|
398
|
+
const configWithFalseValues = path.join(
|
|
399
|
+
testConfigDir,
|
|
400
|
+
"test-config-false-values.json"
|
|
401
|
+
);
|
|
402
|
+
const configWithTrueValues = path.join(
|
|
403
|
+
testConfigDir,
|
|
404
|
+
"test-config-true-values.json"
|
|
405
|
+
);
|
|
406
|
+
const configWithMixedValues = path.join(
|
|
407
|
+
testConfigDir,
|
|
408
|
+
"test-config-mixed-values.json"
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
// Create config file with both set to false
|
|
413
|
+
fs.writeFileSync(
|
|
414
|
+
configWithFalseValues,
|
|
415
|
+
JSON.stringify(
|
|
416
|
+
{
|
|
417
|
+
recursive: false,
|
|
418
|
+
detectSteps: false,
|
|
419
|
+
logLevel: "silent",
|
|
420
|
+
},
|
|
421
|
+
null,
|
|
422
|
+
2
|
|
423
|
+
)
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
// Create config file with both set to true
|
|
427
|
+
fs.writeFileSync(
|
|
428
|
+
configWithTrueValues,
|
|
429
|
+
JSON.stringify(
|
|
430
|
+
{
|
|
431
|
+
recursive: true,
|
|
432
|
+
detectSteps: true,
|
|
433
|
+
logLevel: "silent",
|
|
434
|
+
},
|
|
435
|
+
null,
|
|
436
|
+
2
|
|
437
|
+
)
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
// Create config file with mixed values
|
|
441
|
+
fs.writeFileSync(
|
|
442
|
+
configWithMixedValues,
|
|
443
|
+
JSON.stringify(
|
|
444
|
+
{
|
|
445
|
+
recursive: false,
|
|
446
|
+
detectSteps: true,
|
|
447
|
+
logLevel: "silent",
|
|
448
|
+
},
|
|
449
|
+
null,
|
|
450
|
+
2
|
|
451
|
+
)
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
// Test 1: Config file with false values
|
|
455
|
+
const config1 = await setConfig({
|
|
456
|
+
configPath: configWithFalseValues,
|
|
457
|
+
args: setArgs([
|
|
458
|
+
"node",
|
|
459
|
+
"runTests.js",
|
|
460
|
+
"--config",
|
|
461
|
+
configWithFalseValues,
|
|
462
|
+
]),
|
|
463
|
+
});
|
|
464
|
+
expect(config1.recursive).to.equal(
|
|
465
|
+
false,
|
|
466
|
+
"recursive should be false from config file"
|
|
467
|
+
);
|
|
468
|
+
expect(config1.detectSteps).to.equal(
|
|
469
|
+
false,
|
|
470
|
+
"detectSteps should be false from config file"
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
// Test 2: Config file with true values
|
|
474
|
+
const config2 = await setConfig({
|
|
475
|
+
configPath: configWithTrueValues,
|
|
476
|
+
args: setArgs([
|
|
477
|
+
"node",
|
|
478
|
+
"runTests.js",
|
|
479
|
+
"--config",
|
|
480
|
+
configWithTrueValues,
|
|
481
|
+
]),
|
|
482
|
+
});
|
|
483
|
+
expect(config2.recursive).to.equal(
|
|
484
|
+
true,
|
|
485
|
+
"recursive should be true from config file"
|
|
486
|
+
);
|
|
487
|
+
expect(config2.detectSteps).to.equal(
|
|
488
|
+
true,
|
|
489
|
+
"detectSteps should be true from config file"
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
// Test 3: Config file with mixed values
|
|
493
|
+
const config3 = await setConfig({
|
|
494
|
+
configPath: configWithMixedValues,
|
|
495
|
+
args: setArgs([
|
|
496
|
+
"node",
|
|
497
|
+
"runTests.js",
|
|
498
|
+
"--config",
|
|
499
|
+
configWithMixedValues,
|
|
500
|
+
]),
|
|
501
|
+
});
|
|
502
|
+
expect(config3.recursive).to.equal(
|
|
503
|
+
false,
|
|
504
|
+
"recursive should be false from config file"
|
|
505
|
+
);
|
|
506
|
+
expect(config3.detectSteps).to.equal(
|
|
507
|
+
true,
|
|
508
|
+
"detectSteps should be true from config file"
|
|
509
|
+
);
|
|
510
|
+
} finally {
|
|
511
|
+
// Clean up temporary config files
|
|
512
|
+
if (fs.existsSync(configWithFalseValues)) {
|
|
513
|
+
fs.unlinkSync(configWithFalseValues);
|
|
514
|
+
}
|
|
515
|
+
if (fs.existsSync(configWithTrueValues)) {
|
|
516
|
+
fs.unlinkSync(configWithTrueValues);
|
|
517
|
+
}
|
|
518
|
+
if (fs.existsSync(configWithMixedValues)) {
|
|
519
|
+
fs.unlinkSync(configWithMixedValues);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// Test that environment variable overrides config file for recursive and detectSteps
|
|
525
|
+
it("Environment variable overrides config file for recursive and detectSteps", async function () {
|
|
526
|
+
this.timeout(5000);
|
|
527
|
+
|
|
528
|
+
const testConfigDir = path.resolve("./test");
|
|
529
|
+
const testConfigPath = path.join(
|
|
530
|
+
testConfigDir,
|
|
531
|
+
"test-config-override.json"
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
// Save original environment variable
|
|
535
|
+
const originalEnvConfig = process.env.DOC_DETECTIVE_CONFIG;
|
|
536
|
+
|
|
537
|
+
try {
|
|
538
|
+
// Create config file with true values
|
|
539
|
+
fs.writeFileSync(
|
|
540
|
+
testConfigPath,
|
|
541
|
+
JSON.stringify(
|
|
542
|
+
{
|
|
543
|
+
recursive: true,
|
|
544
|
+
detectSteps: true,
|
|
545
|
+
logLevel: "silent",
|
|
546
|
+
},
|
|
547
|
+
null,
|
|
548
|
+
2
|
|
549
|
+
)
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
// Set environment variable with false values
|
|
553
|
+
process.env.DOC_DETECTIVE_CONFIG = JSON.stringify({
|
|
554
|
+
recursive: false,
|
|
555
|
+
detectSteps: false,
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
// Environment variable should override file config
|
|
559
|
+
const config = await setConfig({
|
|
560
|
+
configPath: testConfigPath,
|
|
561
|
+
args: setArgs(["node", "runTests.js", "--config", testConfigPath]),
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
expect(config.recursive).to.equal(
|
|
565
|
+
false,
|
|
566
|
+
"recursive should be false from env var (overriding config file)"
|
|
567
|
+
);
|
|
568
|
+
expect(config.detectSteps).to.equal(
|
|
569
|
+
false,
|
|
570
|
+
"detectSteps should be false from env var (overriding config file)"
|
|
571
|
+
);
|
|
572
|
+
expect(config.logLevel).to.equal(
|
|
573
|
+
"silent",
|
|
574
|
+
"logLevel should be preserved from config file"
|
|
575
|
+
);
|
|
576
|
+
} finally {
|
|
577
|
+
// Clean up
|
|
578
|
+
if (fs.existsSync(testConfigPath)) {
|
|
579
|
+
fs.unlinkSync(testConfigPath);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Restore the original environment variable value
|
|
583
|
+
if (originalEnvConfig !== undefined) {
|
|
584
|
+
process.env.DOC_DETECTIVE_CONFIG = originalEnvConfig;
|
|
585
|
+
} else {
|
|
586
|
+
delete process.env.DOC_DETECTIVE_CONFIG;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
// Deeply compares two objects
|
|
593
|
+
function deepObjectExpect(actual, expected) {
|
|
594
|
+
// Check that actual has all the keys of expected
|
|
595
|
+
Object.entries(expected).forEach(([key, value]) => {
|
|
596
|
+
// Make sure the property exists in actual
|
|
597
|
+
expect(actual).to.have.property(key);
|
|
598
|
+
|
|
599
|
+
// If value is null, check directly
|
|
600
|
+
if (value === null) {
|
|
601
|
+
expect(actual[key]).to.equal(null);
|
|
602
|
+
}
|
|
603
|
+
// If value is an array, check each item
|
|
604
|
+
else if (Array.isArray(value)) {
|
|
605
|
+
expect(Array.isArray(actual[key])).to.equal(
|
|
606
|
+
true,
|
|
607
|
+
`Expected ${key} to be an array. Expected: ${expected[key]}. Actual: ${actual[key]}.`
|
|
608
|
+
);
|
|
609
|
+
expect(actual[key].length).to.equal(
|
|
610
|
+
value.length,
|
|
611
|
+
`Expected ${key} array to have length ${value.length}. Actual: ${actual[key].length}`
|
|
612
|
+
);
|
|
613
|
+
|
|
614
|
+
// Check each array item
|
|
615
|
+
value.forEach((item, index) => {
|
|
616
|
+
if (typeof item === "object" && item !== null) {
|
|
617
|
+
deepObjectExpect(actual[key][index], item);
|
|
618
|
+
} else {
|
|
619
|
+
expect(actual[key][index]).to.equal(item);
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
// If value is an object but not null, recursively check it
|
|
624
|
+
else if (typeof value === "object") {
|
|
625
|
+
deepObjectExpect(actual[key], expected[key]);
|
|
626
|
+
}
|
|
627
|
+
// Otherwise, check that the value is correct
|
|
628
|
+
else {
|
|
629
|
+
const expectedObject = {};
|
|
630
|
+
expectedObject[key] = value;
|
|
631
|
+
expect(actual).to.deep.include(expectedObject);
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}
|