@featurevisor/core 1.30.1 → 1.32.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/CHANGELOG.md +22 -0
- package/coverage/clover.xml +11 -11
- package/coverage/coverage-final.json +2 -2
- package/coverage/lcov-report/index.html +7 -7
- package/coverage/lcov-report/lib/builder/allocator.js.html +1 -1
- package/coverage/lcov-report/lib/builder/index.html +1 -1
- package/coverage/lcov-report/lib/builder/revision.js.html +1 -1
- package/coverage/lcov-report/lib/builder/traffic.js.html +1 -1
- package/coverage/lcov-report/lib/tester/checkIfObjectsAreEqual.js.html +1 -1
- package/coverage/lcov-report/lib/tester/index.html +5 -5
- package/coverage/lcov-report/lib/tester/matrix.js.html +5 -5
- package/coverage/lcov-report/src/builder/allocator.ts.html +1 -1
- package/coverage/lcov-report/src/builder/index.html +1 -1
- package/coverage/lcov-report/src/builder/revision.ts.html +1 -1
- package/coverage/lcov-report/src/builder/traffic.ts.html +1 -1
- package/coverage/lcov-report/src/tester/checkIfObjectsAreEqual.ts.html +1 -1
- package/coverage/lcov-report/src/tester/index.html +5 -5
- package/coverage/lcov-report/src/tester/matrix.ts.html +5 -5
- package/coverage/lcov.info +30 -22
- package/lib/assess-distribution/index.d.ts +1 -1
- package/lib/assess-distribution/index.js +2 -2
- package/lib/assess-distribution/index.js.map +1 -1
- package/lib/benchmark/index.d.ts +1 -1
- package/lib/benchmark/index.js +2 -2
- package/lib/benchmark/index.js.map +1 -1
- package/lib/builder/buildDatafile.d.ts +1 -1
- package/lib/builder/buildDatafile.js +59 -40
- package/lib/builder/buildDatafile.js.map +1 -1
- package/lib/builder/buildProject.js +87 -50
- package/lib/builder/buildProject.js.map +1 -1
- package/lib/config/projectConfig.d.ts +1 -1
- package/lib/datasource/adapter.d.ts +3 -3
- package/lib/datasource/adapter.js.map +1 -1
- package/lib/datasource/datasource.d.ts +2 -2
- package/lib/datasource/datasource.js.map +1 -1
- package/lib/datasource/filesystemAdapter.d.ts +1 -1
- package/lib/datasource/filesystemAdapter.js +9 -3
- package/lib/datasource/filesystemAdapter.js.map +1 -1
- package/lib/evaluate/index.d.ts +1 -1
- package/lib/evaluate/index.js +10 -7
- package/lib/evaluate/index.js.map +1 -1
- package/lib/find-usage/index.js +60 -26
- package/lib/find-usage/index.js.map +1 -1
- package/lib/linter/featureSchema.d.ts +194 -5
- package/lib/linter/featureSchema.js +70 -60
- package/lib/linter/featureSchema.js.map +1 -1
- package/lib/linter/testSchema.d.ts +1 -1
- package/lib/linter/testSchema.js +16 -13
- package/lib/linter/testSchema.js.map +1 -1
- package/lib/site/generateSiteSearchIndex.js +65 -24
- package/lib/site/generateSiteSearchIndex.js.map +1 -1
- package/lib/tester/matrix.js +2 -2
- package/lib/tester/matrix.js.map +1 -1
- package/lib/tester/testFeature.d.ts +3 -4
- package/lib/tester/testFeature.js +1 -2
- package/lib/tester/testFeature.js.map +1 -1
- package/lib/tester/testProject.d.ts +1 -3
- package/lib/tester/testProject.js +28 -12
- package/lib/tester/testProject.js.map +1 -1
- package/package.json +5 -5
- package/src/assess-distribution/index.ts +3 -3
- package/src/benchmark/index.ts +3 -3
- package/src/builder/buildDatafile.ts +33 -8
- package/src/builder/buildProject.ts +72 -31
- package/src/config/projectConfig.ts +1 -1
- package/src/datasource/adapter.ts +6 -3
- package/src/datasource/datasource.ts +2 -2
- package/src/datasource/filesystemAdapter.ts +12 -4
- package/src/evaluate/index.ts +11 -7
- package/src/find-usage/index.ts +65 -29
- package/src/linter/featureSchema.ts +100 -82
- package/src/linter/testSchema.ts +21 -16
- package/src/site/generateSiteSearchIndex.ts +71 -24
- package/src/tester/matrix.ts +2 -2
- package/src/tester/testFeature.ts +3 -2
- package/src/tester/testProject.ts +27 -8
|
@@ -227,93 +227,102 @@ export function getFeatureZodSchema(
|
|
|
227
227
|
|
|
228
228
|
const groupSegmentsZodSchema = z.union([z.array(groupSegmentZodSchema), groupSegmentZodSchema]);
|
|
229
229
|
|
|
230
|
-
const
|
|
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
|
-
|
|
230
|
+
const exposeSchema = z
|
|
231
|
+
.union([z.boolean(), z.array(z.string().refine((value) => projectConfig.tags.includes(value)))])
|
|
232
|
+
.optional();
|
|
233
|
+
|
|
234
|
+
const rulesSchema = z
|
|
235
|
+
.array(
|
|
236
|
+
z
|
|
237
|
+
.object({
|
|
238
|
+
key: z.string(),
|
|
239
|
+
description: z.string().optional(),
|
|
240
|
+
segments: groupSegmentsZodSchema,
|
|
241
|
+
percentage: z.number().min(0).max(100),
|
|
242
|
+
|
|
243
|
+
enabled: z.boolean().optional(),
|
|
244
|
+
variation: variationValueZodSchema.optional(),
|
|
245
|
+
variables: z.record(variableValueZodSchema).optional(),
|
|
246
|
+
})
|
|
247
|
+
.strict(),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
// must have at least one rule
|
|
251
|
+
.refine(
|
|
252
|
+
(value) => value.length > 0,
|
|
253
|
+
() => ({
|
|
254
|
+
message: "Must have at least one rule",
|
|
255
|
+
}),
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
// duplicate rules
|
|
259
|
+
.refine(
|
|
260
|
+
(value) => {
|
|
261
|
+
const keys = value.map((v) => v.key);
|
|
262
|
+
return keys.length === new Set(keys).size;
|
|
263
|
+
},
|
|
264
|
+
(value) => ({
|
|
265
|
+
message: "Duplicate rule keys found: " + value.map((v) => v.key).join(", "),
|
|
266
|
+
}),
|
|
267
|
+
)
|
|
261
268
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
(value) => ({
|
|
269
|
-
message: "Duplicate rule keys found: " + value.map((v) => v.key).join(", "),
|
|
270
|
-
}),
|
|
271
|
-
)
|
|
269
|
+
// enforce catch-all rule
|
|
270
|
+
.refine(
|
|
271
|
+
(value) => {
|
|
272
|
+
if (!projectConfig.enforceCatchAllRule) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
272
275
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
const hasCatchAllAsLastRule = value[value.length - 1].segments === "*";
|
|
277
|
+
return hasCatchAllAsLastRule;
|
|
278
|
+
},
|
|
279
|
+
() => ({
|
|
280
|
+
message: `Missing catch-all rule with \`segments: "*"\` at the end`,
|
|
281
|
+
}),
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const forceSchema = z
|
|
285
|
+
.array(
|
|
286
|
+
z.union([
|
|
287
|
+
z
|
|
288
|
+
.object({
|
|
289
|
+
segments: groupSegmentsZodSchema,
|
|
290
|
+
enabled: z.boolean().optional(),
|
|
291
|
+
variation: variationValueZodSchema.optional(),
|
|
292
|
+
variables: z.record(variableValueZodSchema).optional(),
|
|
293
|
+
})
|
|
294
|
+
.strict(),
|
|
295
|
+
z
|
|
296
|
+
.object({
|
|
297
|
+
conditions: conditionsZodSchema,
|
|
298
|
+
enabled: z.boolean().optional(),
|
|
299
|
+
variation: variationValueZodSchema.optional(),
|
|
300
|
+
variables: z.record(variableValueZodSchema).optional(),
|
|
301
|
+
})
|
|
302
|
+
.strict(),
|
|
303
|
+
]),
|
|
304
|
+
)
|
|
305
|
+
.optional();
|
|
279
306
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}),
|
|
286
|
-
),
|
|
287
|
-
force: z
|
|
288
|
-
.array(
|
|
289
|
-
z.union([
|
|
290
|
-
z
|
|
291
|
-
.object({
|
|
292
|
-
segments: groupSegmentsZodSchema,
|
|
293
|
-
enabled: z.boolean().optional(),
|
|
294
|
-
variation: variationValueZodSchema.optional(),
|
|
295
|
-
variables: z.record(variableValueZodSchema).optional(),
|
|
296
|
-
})
|
|
297
|
-
.strict(),
|
|
298
|
-
z
|
|
299
|
-
.object({
|
|
300
|
-
conditions: conditionsZodSchema,
|
|
301
|
-
enabled: z.boolean().optional(),
|
|
302
|
-
variation: variationValueZodSchema.optional(),
|
|
303
|
-
variables: z.record(variableValueZodSchema).optional(),
|
|
304
|
-
})
|
|
305
|
-
.strict(),
|
|
306
|
-
]),
|
|
307
|
-
)
|
|
308
|
-
.optional(),
|
|
307
|
+
const environmentZodSchema = z
|
|
308
|
+
.object({
|
|
309
|
+
expose: exposeSchema,
|
|
310
|
+
rules: rulesSchema,
|
|
311
|
+
force: forceSchema,
|
|
309
312
|
})
|
|
310
313
|
.strict();
|
|
311
314
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
let allEnvironmentsZodSchema: z.ZodTypeAny = z.never();
|
|
316
|
+
|
|
317
|
+
if (Array.isArray(projectConfig.environments)) {
|
|
318
|
+
const allEnvironmentsSchema = {};
|
|
319
|
+
|
|
320
|
+
projectConfig.environments.forEach((environmentKey) => {
|
|
321
|
+
allEnvironmentsSchema[environmentKey] = environmentZodSchema;
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
allEnvironmentsZodSchema = z.object(allEnvironmentsSchema).strict();
|
|
325
|
+
}
|
|
317
326
|
|
|
318
327
|
const attributeKeyZodSchema = z.string().refine(
|
|
319
328
|
(value) => value === "*" || availableAttributeKeys.includes(value),
|
|
@@ -447,7 +456,16 @@ export function getFeatureZodSchema(
|
|
|
447
456
|
}),
|
|
448
457
|
)
|
|
449
458
|
.optional(),
|
|
450
|
-
|
|
459
|
+
|
|
460
|
+
// with environments
|
|
461
|
+
environments: Array.isArray(projectConfig.environments)
|
|
462
|
+
? allEnvironmentsZodSchema
|
|
463
|
+
: z.never().optional(),
|
|
464
|
+
|
|
465
|
+
// no environments
|
|
466
|
+
expose: projectConfig.environments === false ? exposeSchema : z.never().optional(),
|
|
467
|
+
rules: projectConfig.environments === false ? rulesSchema : z.never().optional(),
|
|
468
|
+
force: projectConfig.environments === false ? forceSchema : z.never().optional(),
|
|
451
469
|
})
|
|
452
470
|
.strict()
|
|
453
471
|
.superRefine((value, ctx) => {
|
package/src/linter/testSchema.ts
CHANGED
|
@@ -59,24 +59,29 @@ export function getTestsZodSchema(
|
|
|
59
59
|
// because of supporting matrix
|
|
60
60
|
z.string(),
|
|
61
61
|
]),
|
|
62
|
-
environment:
|
|
63
|
-
(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
environment: Array.isArray(projectConfig.environments)
|
|
63
|
+
? z.string().refine(
|
|
64
|
+
(value) => {
|
|
65
|
+
if (value.indexOf("${{") === 0) {
|
|
66
|
+
// allow unknown strings for matrix
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
// otherwise only known environments should be passed
|
|
71
|
+
if (
|
|
72
|
+
Array.isArray(projectConfig.environments) &&
|
|
73
|
+
projectConfig.environments.includes(value)
|
|
74
|
+
) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
return false;
|
|
79
|
+
},
|
|
80
|
+
(value) => ({
|
|
81
|
+
message: `Unknown environment "${value}"`,
|
|
82
|
+
}),
|
|
83
|
+
)
|
|
84
|
+
: z.never().optional(),
|
|
80
85
|
context: z.record(z.unknown()),
|
|
81
86
|
expectedToBeEnabled: z.boolean(),
|
|
82
87
|
expectedVariation: z.string().optional(),
|
|
@@ -23,6 +23,10 @@ export async function generateSiteSearchIndex(
|
|
|
23
23
|
|
|
24
24
|
const result: SearchIndex = {
|
|
25
25
|
links: undefined,
|
|
26
|
+
projectConfig: {
|
|
27
|
+
tags: projectConfig.tags,
|
|
28
|
+
environments: projectConfig.environments,
|
|
29
|
+
},
|
|
26
30
|
entities: {
|
|
27
31
|
attributes: [],
|
|
28
32
|
segments: [],
|
|
@@ -115,10 +119,52 @@ export async function generateSiteSearchIndex(
|
|
|
115
119
|
});
|
|
116
120
|
}
|
|
117
121
|
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
// with environments
|
|
123
|
+
if (parsed.environments) {
|
|
124
|
+
Object.keys(parsed.environments).forEach((environmentKey) => {
|
|
125
|
+
const env = parsed.environments[environmentKey];
|
|
126
|
+
|
|
127
|
+
env.rules.forEach((rule) => {
|
|
128
|
+
if (rule.segments && rule.segments !== "*") {
|
|
129
|
+
extractSegmentKeysFromGroupSegments(rule.segments).forEach((segmentKey) => {
|
|
130
|
+
if (!segmentsUsedInFeatures[segmentKey]) {
|
|
131
|
+
segmentsUsedInFeatures[segmentKey] = new Set();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
segmentsUsedInFeatures[segmentKey].add(entityName);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (env.force) {
|
|
140
|
+
env.force.forEach((force) => {
|
|
141
|
+
if (force.segments && force.segments !== "*") {
|
|
142
|
+
extractSegmentKeysFromGroupSegments(force.segments).forEach((segmentKey) => {
|
|
143
|
+
if (!segmentsUsedInFeatures[segmentKey]) {
|
|
144
|
+
segmentsUsedInFeatures[segmentKey] = new Set();
|
|
145
|
+
}
|
|
120
146
|
|
|
121
|
-
|
|
147
|
+
segmentsUsedInFeatures[segmentKey].add(entityName);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (force.conditions) {
|
|
152
|
+
extractAttributeKeysFromConditions(force.conditions).forEach((attributeKey) => {
|
|
153
|
+
if (!attributesUsedInFeatures[attributeKey]) {
|
|
154
|
+
attributesUsedInFeatures[attributeKey] = new Set();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
attributesUsedInFeatures[attributeKey].add(entityName);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// no environments
|
|
166
|
+
if (parsed.rules) {
|
|
167
|
+
parsed.rules.forEach((rule) => {
|
|
122
168
|
if (rule.segments && rule.segments !== "*") {
|
|
123
169
|
extractSegmentKeysFromGroupSegments(rule.segments).forEach((segmentKey) => {
|
|
124
170
|
if (!segmentsUsedInFeatures[segmentKey]) {
|
|
@@ -129,32 +175,33 @@ export async function generateSiteSearchIndex(
|
|
|
129
175
|
});
|
|
130
176
|
}
|
|
131
177
|
});
|
|
178
|
+
}
|
|
132
179
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
if (parsed.force) {
|
|
181
|
+
parsed.force.forEach((force) => {
|
|
182
|
+
if (force.segments && force.segments !== "*") {
|
|
183
|
+
extractSegmentKeysFromGroupSegments(force.segments).forEach((segmentKey) => {
|
|
184
|
+
if (!segmentsUsedInFeatures[segmentKey]) {
|
|
185
|
+
segmentsUsedInFeatures[segmentKey] = new Set();
|
|
186
|
+
}
|
|
140
187
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
188
|
+
segmentsUsedInFeatures[segmentKey].add(entityName);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
144
191
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
192
|
+
if (force.conditions) {
|
|
193
|
+
extractAttributeKeysFromConditions(force.conditions).forEach((attributeKey) => {
|
|
194
|
+
if (!attributesUsedInFeatures[attributeKey]) {
|
|
195
|
+
attributesUsedInFeatures[attributeKey] = new Set();
|
|
196
|
+
}
|
|
150
197
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
});
|
|
198
|
+
attributesUsedInFeatures[attributeKey].add(entityName);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
157
203
|
|
|
204
|
+
// push
|
|
158
205
|
result.entities.features.push({
|
|
159
206
|
...parsed,
|
|
160
207
|
key: entityName,
|
package/src/tester/matrix.ts
CHANGED
|
@@ -105,7 +105,7 @@ export function getFeatureAssertionsFromMatrix(
|
|
|
105
105
|
): FeatureAssertion[] {
|
|
106
106
|
if (!assertionWithMatrix.matrix) {
|
|
107
107
|
const assertion = { ...assertionWithMatrix };
|
|
108
|
-
assertion.description = `Assertion #${aIndex + 1}
|
|
108
|
+
assertion.description = `Assertion #${aIndex + 1}:${assertion.environment ? ` (${assertion.environment})` : ""} ${
|
|
109
109
|
assertion.description || `at ${assertion.at}%`
|
|
110
110
|
}`;
|
|
111
111
|
|
|
@@ -118,7 +118,7 @@ export function getFeatureAssertionsFromMatrix(
|
|
|
118
118
|
for (let cIndex = 0; cIndex < combinations.length; cIndex++) {
|
|
119
119
|
const combination = combinations[cIndex];
|
|
120
120
|
const assertion = applyCombinationToFeatureAssertion(combination, assertionWithMatrix);
|
|
121
|
-
assertion.description = `Assertion #${aIndex + 1}
|
|
121
|
+
assertion.description = `Assertion #${aIndex + 1}:${assertion.environment ? ` (${assertion.environment})` : ""} ${
|
|
122
122
|
assertion.description || `at ${assertion.at}%`
|
|
123
123
|
}`;
|
|
124
124
|
|
|
@@ -13,6 +13,7 @@ import { ProjectConfig } from "../config";
|
|
|
13
13
|
import { checkIfArraysAreEqual } from "./checkIfArraysAreEqual";
|
|
14
14
|
import { checkIfObjectsAreEqual } from "./checkIfObjectsAreEqual";
|
|
15
15
|
import { getFeatureAssertionsFromMatrix } from "./matrix";
|
|
16
|
+
import type { DatafileContentByEnvironment } from "./testProject";
|
|
16
17
|
|
|
17
18
|
export async function testFeature(
|
|
18
19
|
datasource: Datasource,
|
|
@@ -20,7 +21,7 @@ export async function testFeature(
|
|
|
20
21
|
test: TestFeature,
|
|
21
22
|
options: { verbose?: boolean; showDatafile?: boolean } = {},
|
|
22
23
|
patterns,
|
|
23
|
-
datafileContentByEnvironment:
|
|
24
|
+
datafileContentByEnvironment: DatafileContentByEnvironment,
|
|
24
25
|
): Promise<TestResult> {
|
|
25
26
|
const testStartTime = Date.now();
|
|
26
27
|
const featureKey = test.feature;
|
|
@@ -54,7 +55,7 @@ export async function testFeature(
|
|
|
54
55
|
continue;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
const datafileContent = datafileContentByEnvironment
|
|
58
|
+
const datafileContent = datafileContentByEnvironment.get(assertion.environment || false);
|
|
58
59
|
|
|
59
60
|
if (options.showDatafile) {
|
|
60
61
|
console.log("");
|
|
@@ -36,9 +36,7 @@ export interface ExecutionResult {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export
|
|
40
|
-
[environment: string]: DatafileContent;
|
|
41
|
-
}
|
|
39
|
+
export type DatafileContentByEnvironment = Map<string | false, DatafileContent>;
|
|
42
40
|
|
|
43
41
|
export async function executeTest(
|
|
44
42
|
testFile: string,
|
|
@@ -151,23 +149,44 @@ export async function testProject(
|
|
|
151
149
|
let passedAssertionsCount = 0;
|
|
152
150
|
let failedAssertionsCount = 0;
|
|
153
151
|
|
|
154
|
-
const datafileContentByEnvironment: DatafileContentByEnvironment =
|
|
152
|
+
const datafileContentByEnvironment: DatafileContentByEnvironment = new Map();
|
|
153
|
+
|
|
154
|
+
// with environments
|
|
155
|
+
if (Array.isArray(projectConfig.environments)) {
|
|
156
|
+
for (const environment of projectConfig.environments) {
|
|
157
|
+
const existingState = await datasource.readState(environment);
|
|
158
|
+
const datafileContent = await buildDatafile(
|
|
159
|
+
projectConfig,
|
|
160
|
+
datasource,
|
|
161
|
+
{
|
|
162
|
+
schemaVersion: options.schemaVersion || SCHEMA_VERSION,
|
|
163
|
+
revision: "include-all-features",
|
|
164
|
+
environment: environment,
|
|
165
|
+
inflate: options.inflate,
|
|
166
|
+
},
|
|
167
|
+
existingState,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
datafileContentByEnvironment.set(environment, datafileContent);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
155
173
|
|
|
156
|
-
|
|
157
|
-
|
|
174
|
+
// no environments
|
|
175
|
+
if (projectConfig.environments === false) {
|
|
176
|
+
const existingState = await datasource.readState(false);
|
|
158
177
|
const datafileContent = await buildDatafile(
|
|
159
178
|
projectConfig,
|
|
160
179
|
datasource,
|
|
161
180
|
{
|
|
162
181
|
schemaVersion: options.schemaVersion || SCHEMA_VERSION,
|
|
163
182
|
revision: "include-all-features",
|
|
164
|
-
environment:
|
|
183
|
+
environment: false,
|
|
165
184
|
inflate: options.inflate,
|
|
166
185
|
},
|
|
167
186
|
existingState,
|
|
168
187
|
);
|
|
169
188
|
|
|
170
|
-
datafileContentByEnvironment
|
|
189
|
+
datafileContentByEnvironment.set(false, datafileContent);
|
|
171
190
|
}
|
|
172
191
|
|
|
173
192
|
for (const testFile of testFiles) {
|