@featurevisor/core 0.53.2 → 0.53.4
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/.eslintcache +1 -1
- package/CHANGELOG.md +16 -0
- package/coverage/clover.xml +2 -2
- package/coverage/lcov-report/index.html +1 -1
- 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/traffic.js.html +1 -1
- 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/traffic.ts.html +1 -1
- package/lib/builder/buildDatafile.d.ts +1 -1
- package/lib/builder/buildDatafile.js +241 -168
- package/lib/builder/buildDatafile.js.map +1 -1
- package/lib/builder/buildProject.d.ts +1 -2
- package/lib/builder/buildProject.js +95 -45
- package/lib/builder/buildProject.js.map +1 -1
- package/lib/builder/getFeatureRanges.d.ts +1 -1
- package/lib/builder/getFeatureRanges.js +92 -31
- package/lib/builder/getFeatureRanges.js.map +1 -1
- package/lib/datasource/datasource.d.ts +23 -17
- package/lib/datasource/datasource.js +166 -69
- package/lib/datasource/datasource.js.map +1 -1
- package/lib/datasource/parsers.js +2 -2
- package/lib/datasource/parsers.js.map +1 -1
- package/lib/find-duplicate-segments/findDuplicateSegments.d.ts +1 -1
- package/lib/find-duplicate-segments/findDuplicateSegments.js +75 -18
- package/lib/find-duplicate-segments/findDuplicateSegments.js.map +1 -1
- package/lib/find-duplicate-segments/index.d.ts +1 -1
- package/lib/find-duplicate-segments/index.js +56 -9
- package/lib/find-duplicate-segments/index.js.map +1 -1
- package/lib/generate-code/index.d.ts +1 -1
- package/lib/generate-code/index.js +67 -23
- package/lib/generate-code/index.js.map +1 -1
- package/lib/generate-code/typescript.d.ts +1 -1
- package/lib/generate-code/typescript.js +139 -72
- package/lib/generate-code/typescript.js.map +1 -1
- package/lib/linter/checkCircularDependency.d.ts +1 -1
- package/lib/linter/checkCircularDependency.js +78 -22
- package/lib/linter/checkCircularDependency.js.map +1 -1
- package/lib/linter/groupSchema.js +79 -28
- package/lib/linter/groupSchema.js.map +1 -1
- package/lib/linter/lintProject.js +119 -103
- package/lib/linter/lintProject.js.map +1 -1
- package/lib/restore.d.ts +1 -1
- package/lib/restore.js +53 -11
- package/lib/restore.js.map +1 -1
- package/lib/site/exportSite.d.ts +1 -1
- package/lib/site/exportSite.js +64 -21
- package/lib/site/exportSite.js.map +1 -1
- package/lib/site/generateSiteSearchIndex.d.ts +1 -1
- package/lib/site/generateSiteSearchIndex.js +203 -111
- package/lib/site/generateSiteSearchIndex.js.map +1 -1
- package/lib/tester/testFeature.d.ts +1 -1
- package/lib/tester/testFeature.js +130 -60
- package/lib/tester/testFeature.js.map +1 -1
- package/lib/tester/testProject.d.ts +1 -1
- package/lib/tester/testProject.js +105 -48
- package/lib/tester/testProject.js.map +1 -1
- package/lib/tester/testSegment.d.ts +1 -1
- package/lib/tester/testSegment.js +69 -21
- package/lib/tester/testSegment.js.map +1 -1
- package/lib/utils.d.ts +0 -2
- package/lib/utils.js +1 -15
- package/lib/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/builder/buildDatafile.ts +9 -9
- package/src/builder/buildProject.ts +4 -24
- package/src/builder/getFeatureRanges.ts +4 -4
- package/src/datasource/datasource.ts +66 -60
- package/src/datasource/parsers.ts +2 -2
- package/src/find-duplicate-segments/findDuplicateSegments.ts +9 -6
- package/src/find-duplicate-segments/index.ts +5 -2
- package/src/generate-code/index.ts +2 -2
- package/src/generate-code/typescript.ts +42 -25
- package/src/linter/checkCircularDependency.ts +4 -4
- package/src/linter/groupSchema.ts +3 -3
- package/src/linter/lintProject.ts +53 -60
- package/src/restore.ts +1 -1
- package/src/site/exportSite.ts +2 -2
- package/src/site/generateSiteSearchIndex.ts +14 -14
- package/src/tester/testFeature.ts +12 -13
- package/src/tester/testProject.ts +8 -5
- package/src/tester/testSegment.ts +3 -3
- package/src/utils.ts +0 -18
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
// for use in node only
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
|
|
4
2
|
import * as Joi from "joi";
|
|
5
3
|
|
|
6
4
|
import { Datasource } from "../datasource";
|
|
@@ -25,13 +23,13 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
25
23
|
const availableFeatureKeys: string[] = [];
|
|
26
24
|
|
|
27
25
|
// lint attributes
|
|
28
|
-
const attributes = datasource.listAttributes();
|
|
26
|
+
const attributes = await datasource.listAttributes();
|
|
29
27
|
console.log(`Linting ${attributes.length} attributes...\n`);
|
|
30
28
|
|
|
31
29
|
const attributeJoiSchema = getAttributeJoiSchema();
|
|
32
30
|
|
|
33
31
|
for (const key of attributes) {
|
|
34
|
-
const parsed = datasource.readAttribute(key);
|
|
32
|
+
const parsed = await datasource.readAttribute(key);
|
|
35
33
|
availableAttributeKeys.push(key);
|
|
36
34
|
|
|
37
35
|
try {
|
|
@@ -50,14 +48,14 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
// lint segments
|
|
53
|
-
const segments = datasource.listSegments();
|
|
51
|
+
const segments = await datasource.listSegments();
|
|
54
52
|
console.log(`\nLinting ${segments.length} segments...\n`);
|
|
55
53
|
|
|
56
54
|
const conditionsJoiSchema = getConditionsJoiSchema(projectConfig, availableAttributeKeys);
|
|
57
55
|
const segmentJoiSchema = getSegmentJoiSchema(projectConfig, conditionsJoiSchema);
|
|
58
56
|
|
|
59
57
|
for (const key of segments) {
|
|
60
|
-
const parsed = datasource.readSegment(key);
|
|
58
|
+
const parsed = await datasource.readSegment(key);
|
|
61
59
|
availableSegmentKeys.push(key);
|
|
62
60
|
|
|
63
61
|
try {
|
|
@@ -75,38 +73,8 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
// lint groups
|
|
79
|
-
|
|
80
|
-
if (fs.existsSync(projectConfig.groupsDirectoryPath)) {
|
|
81
|
-
const groups = datasource.listGroups();
|
|
82
|
-
console.log(`\nLinting ${groups.length} groups...\n`);
|
|
83
|
-
|
|
84
|
-
// @TODO: feature it slots can be from availableFeatureKeys only
|
|
85
|
-
const groupJoiSchema = getGroupJoiSchema(projectConfig, datasource, availableFeatureKeys);
|
|
86
|
-
|
|
87
|
-
for (const key of groups) {
|
|
88
|
-
const parsed = datasource.readGroup(key);
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
await groupJoiSchema.validateAsync(parsed);
|
|
92
|
-
} catch (e) {
|
|
93
|
-
console.log(" =>", key);
|
|
94
|
-
|
|
95
|
-
if (e instanceof Joi.ValidationError) {
|
|
96
|
-
printJoiError(e);
|
|
97
|
-
} else {
|
|
98
|
-
console.log(e);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
hasError = true;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// @TODO: feature cannot exist in multiple groups
|
|
107
|
-
|
|
108
76
|
// lint features
|
|
109
|
-
const features = datasource.listFeatures();
|
|
77
|
+
const features = await datasource.listFeatures();
|
|
110
78
|
console.log(`\nLinting ${features.length} features...\n`);
|
|
111
79
|
|
|
112
80
|
const featureJoiSchema = getFeatureJoiSchema(
|
|
@@ -117,7 +85,7 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
117
85
|
);
|
|
118
86
|
|
|
119
87
|
for (const key of features) {
|
|
120
|
-
const parsed = datasource.readFeature(key);
|
|
88
|
+
const parsed = await datasource.readFeature(key);
|
|
121
89
|
availableFeatureKeys.push(key);
|
|
122
90
|
|
|
123
91
|
try {
|
|
@@ -136,7 +104,7 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
136
104
|
|
|
137
105
|
if (parsed.required) {
|
|
138
106
|
try {
|
|
139
|
-
checkForCircularDependencyInRequired(datasource, key, parsed.required);
|
|
107
|
+
await checkForCircularDependencyInRequired(datasource, key, parsed.required);
|
|
140
108
|
} catch (e) {
|
|
141
109
|
console.log(" =>", key);
|
|
142
110
|
console.log(" => Error:", e.message);
|
|
@@ -145,33 +113,58 @@ export async function lintProject(projectConfig: ProjectConfig): Promise<boolean
|
|
|
145
113
|
}
|
|
146
114
|
}
|
|
147
115
|
|
|
148
|
-
// lint
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
console.log(`\nLinting ${tests.length} tests...\n`);
|
|
116
|
+
// lint groups
|
|
117
|
+
const groups = await datasource.listGroups();
|
|
118
|
+
console.log(`\nLinting ${groups.length} groups...\n`);
|
|
152
119
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
availableFeatureKeys,
|
|
156
|
-
availableSegmentKeys,
|
|
157
|
-
);
|
|
120
|
+
// @TODO: feature it slots can be from availableFeatureKeys only
|
|
121
|
+
const groupJoiSchema = getGroupJoiSchema(projectConfig, datasource, availableFeatureKeys);
|
|
158
122
|
|
|
159
|
-
|
|
160
|
-
|
|
123
|
+
for (const key of groups) {
|
|
124
|
+
const parsed = await datasource.readGroup(key);
|
|
161
125
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
126
|
+
try {
|
|
127
|
+
await groupJoiSchema.validateAsync(parsed);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
console.log(" =>", key);
|
|
130
|
+
|
|
131
|
+
if (e instanceof Joi.ValidationError) {
|
|
132
|
+
printJoiError(e);
|
|
133
|
+
} else {
|
|
134
|
+
console.log(e);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
hasError = true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
166
140
|
|
|
167
|
-
|
|
168
|
-
printJoiError(e);
|
|
169
|
-
} else {
|
|
170
|
-
console.log(e);
|
|
171
|
-
}
|
|
141
|
+
// @TODO: feature cannot exist in multiple groups
|
|
172
142
|
|
|
173
|
-
|
|
143
|
+
// lint tests
|
|
144
|
+
const tests = await datasource.listTests();
|
|
145
|
+
console.log(`\nLinting ${tests.length} tests...\n`);
|
|
146
|
+
|
|
147
|
+
const testsJoiSchema = getTestsJoiSchema(
|
|
148
|
+
projectConfig,
|
|
149
|
+
availableFeatureKeys,
|
|
150
|
+
availableSegmentKeys,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
for (const key of tests) {
|
|
154
|
+
const parsed = await datasource.readTest(key);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await testsJoiSchema.validateAsync(parsed);
|
|
158
|
+
} catch (e) {
|
|
159
|
+
console.log(" =>", key);
|
|
160
|
+
|
|
161
|
+
if (e instanceof Joi.ValidationError) {
|
|
162
|
+
printJoiError(e);
|
|
163
|
+
} else {
|
|
164
|
+
console.log(e);
|
|
174
165
|
}
|
|
166
|
+
|
|
167
|
+
hasError = true;
|
|
175
168
|
}
|
|
176
169
|
}
|
|
177
170
|
|
package/src/restore.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { execSync } from "child_process";
|
|
|
3
3
|
|
|
4
4
|
import { ProjectConfig } from "./config";
|
|
5
5
|
|
|
6
|
-
export function restoreProject(rootDirectoryPath, projectConfig: ProjectConfig) {
|
|
6
|
+
export async function restoreProject(rootDirectoryPath, projectConfig: ProjectConfig) {
|
|
7
7
|
const relativeStateDirPath = path.relative(rootDirectoryPath, projectConfig.stateDirectoryPath);
|
|
8
8
|
const cmd = `git checkout -- ${relativeStateDirPath}${path.sep}`;
|
|
9
9
|
|
package/src/site/exportSite.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { generateHistory } from "./generateHistory";
|
|
|
9
9
|
import { getRepoDetails } from "./getRepoDetails";
|
|
10
10
|
import { generateSiteSearchIndex } from "./generateSiteSearchIndex";
|
|
11
11
|
|
|
12
|
-
export function exportSite(rootDirectoryPath: string, projectConfig: ProjectConfig) {
|
|
12
|
+
export async function exportSite(rootDirectoryPath: string, projectConfig: ProjectConfig) {
|
|
13
13
|
const hasError = false;
|
|
14
14
|
|
|
15
15
|
mkdirp.sync(projectConfig.siteExportDirectoryPath);
|
|
@@ -30,7 +30,7 @@ export function exportSite(rootDirectoryPath: string, projectConfig: ProjectConf
|
|
|
30
30
|
|
|
31
31
|
// site search index
|
|
32
32
|
const repoDetails = getRepoDetails();
|
|
33
|
-
const searchIndex = generateSiteSearchIndex(
|
|
33
|
+
const searchIndex = await generateSiteSearchIndex(
|
|
34
34
|
rootDirectoryPath,
|
|
35
35
|
projectConfig,
|
|
36
36
|
fullHistory,
|
|
@@ -15,12 +15,12 @@ import { getRelativePaths } from "./getRelativePaths";
|
|
|
15
15
|
import { getLastModifiedFromHistory } from "./getLastModifiedFromHistory";
|
|
16
16
|
import { RepoDetails } from "./getRepoDetails";
|
|
17
17
|
|
|
18
|
-
export function generateSiteSearchIndex(
|
|
18
|
+
export async function generateSiteSearchIndex(
|
|
19
19
|
rootDirectoryPath: string,
|
|
20
20
|
projectConfig: ProjectConfig,
|
|
21
21
|
fullHistory: HistoryEntry[],
|
|
22
22
|
repoDetails: RepoDetails | undefined,
|
|
23
|
-
): SearchIndex {
|
|
23
|
+
): Promise<SearchIndex> {
|
|
24
24
|
const result: SearchIndex = {
|
|
25
25
|
links: undefined,
|
|
26
26
|
entities: {
|
|
@@ -77,9 +77,9 @@ export function generateSiteSearchIndex(
|
|
|
77
77
|
} = {};
|
|
78
78
|
|
|
79
79
|
// features
|
|
80
|
-
const featureFiles = datasource.listFeatures();
|
|
81
|
-
|
|
82
|
-
const parsed = datasource.readFeature(entityName);
|
|
80
|
+
const featureFiles = await datasource.listFeatures();
|
|
81
|
+
for (const entityName of featureFiles) {
|
|
82
|
+
const parsed = await datasource.readFeature(entityName);
|
|
83
83
|
|
|
84
84
|
if (Array.isArray(parsed.variations)) {
|
|
85
85
|
parsed.variations.forEach((variation) => {
|
|
@@ -160,12 +160,12 @@ export function generateSiteSearchIndex(
|
|
|
160
160
|
key: entityName,
|
|
161
161
|
lastModified: getLastModifiedFromHistory(fullHistory, "feature", entityName),
|
|
162
162
|
});
|
|
163
|
-
}
|
|
163
|
+
}
|
|
164
164
|
|
|
165
165
|
// segments
|
|
166
|
-
const segmentFiles = datasource.listSegments();
|
|
167
|
-
|
|
168
|
-
const parsed = datasource.readSegment(entityName);
|
|
166
|
+
const segmentFiles = await datasource.listSegments();
|
|
167
|
+
for (const entityName of segmentFiles) {
|
|
168
|
+
const parsed = await datasource.readSegment(entityName);
|
|
169
169
|
|
|
170
170
|
extractAttributeKeysFromConditions(parsed.conditions as Condition | Condition[]).forEach(
|
|
171
171
|
(attributeKey) => {
|
|
@@ -183,12 +183,12 @@ export function generateSiteSearchIndex(
|
|
|
183
183
|
lastModified: getLastModifiedFromHistory(fullHistory, "segment", entityName),
|
|
184
184
|
usedInFeatures: Array.from(segmentsUsedInFeatures[entityName] || []),
|
|
185
185
|
});
|
|
186
|
-
}
|
|
186
|
+
}
|
|
187
187
|
|
|
188
188
|
// attributes
|
|
189
|
-
const attributeFiles = datasource.listAttributes();
|
|
190
|
-
|
|
191
|
-
const parsed = datasource.readAttribute(entityName);
|
|
189
|
+
const attributeFiles = await datasource.listAttributes();
|
|
190
|
+
for (const entityName of attributeFiles) {
|
|
191
|
+
const parsed = await datasource.readAttribute(entityName);
|
|
192
192
|
|
|
193
193
|
result.entities.attributes.push({
|
|
194
194
|
...parsed,
|
|
@@ -197,7 +197,7 @@ export function generateSiteSearchIndex(
|
|
|
197
197
|
usedInFeatures: Array.from(attributesUsedInFeatures[entityName] || []),
|
|
198
198
|
usedInSegments: Array.from(attributesUsedInSegments[entityName] || []),
|
|
199
199
|
});
|
|
200
|
-
}
|
|
200
|
+
}
|
|
201
201
|
|
|
202
202
|
return result;
|
|
203
203
|
}
|
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { TestFeature, ExistingState } from "@featurevisor/types";
|
|
1
|
+
import { TestFeature } from "@featurevisor/types";
|
|
4
2
|
import { createInstance, MAX_BUCKETED_NUMBER } from "@featurevisor/sdk";
|
|
5
3
|
|
|
6
4
|
import { Datasource } from "../datasource";
|
|
7
5
|
import { ProjectConfig } from "../config";
|
|
8
|
-
import { buildDatafile
|
|
6
|
+
import { buildDatafile } from "../builder";
|
|
9
7
|
import { SCHEMA_VERSION } from "../config";
|
|
10
8
|
|
|
11
9
|
import { checkIfArraysAreEqual } from "./checkIfArraysAreEqual";
|
|
12
10
|
import { checkIfObjectsAreEqual } from "./checkIfObjectsAreEqual";
|
|
13
11
|
import { CLI_FORMAT_BOLD, CLI_FORMAT_RED } from "./cliFormat";
|
|
14
12
|
|
|
15
|
-
export function testFeature(
|
|
13
|
+
export async function testFeature(
|
|
16
14
|
datasource: Datasource,
|
|
17
15
|
projectConfig: ProjectConfig,
|
|
18
16
|
test: TestFeature,
|
|
19
|
-
): boolean {
|
|
17
|
+
): Promise<boolean> {
|
|
20
18
|
let hasError = false;
|
|
21
19
|
const featureKey = test.feature;
|
|
22
20
|
|
|
23
21
|
console.log(CLI_FORMAT_BOLD, ` Feature "${featureKey}":`);
|
|
24
22
|
|
|
25
|
-
test.assertions.
|
|
23
|
+
for (let aIndex = 0; aIndex < test.assertions.length; aIndex++) {
|
|
24
|
+
const assertion = test.assertions[aIndex];
|
|
26
25
|
const description = assertion.description || `at ${assertion.at}%`;
|
|
27
26
|
|
|
28
27
|
console.log(` Assertion #${aIndex + 1}: (${assertion.environment}) ${description}`);
|
|
29
28
|
|
|
30
|
-
const
|
|
29
|
+
const requiredChain = await datasource.getRequiredFeaturesChain(test.feature);
|
|
30
|
+
const featuresToInclude = Array.from(requiredChain);
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const existingState = await datasource.readState(assertion.environment);
|
|
33
|
+
const datafileContent = await buildDatafile(
|
|
33
34
|
projectConfig,
|
|
34
35
|
datasource,
|
|
35
36
|
{
|
|
@@ -38,9 +39,7 @@ export function testFeature(
|
|
|
38
39
|
environment: assertion.environment,
|
|
39
40
|
features: featuresToInclude,
|
|
40
41
|
},
|
|
41
|
-
|
|
42
|
-
fs.readFileSync(getExistingStateFilePath(projectConfig, assertion.environment), "utf8"),
|
|
43
|
-
) as ExistingState,
|
|
42
|
+
existingState,
|
|
44
43
|
);
|
|
45
44
|
|
|
46
45
|
const sdk = createInstance({
|
|
@@ -110,7 +109,7 @@ export function testFeature(
|
|
|
110
109
|
}
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
|
-
}
|
|
112
|
+
}
|
|
114
113
|
|
|
115
114
|
return hasError;
|
|
116
115
|
}
|
|
@@ -9,7 +9,10 @@ import { testSegment } from "./testSegment";
|
|
|
9
9
|
import { testFeature } from "./testFeature";
|
|
10
10
|
import { CLI_FORMAT_BOLD, CLI_FORMAT_GREEN, CLI_FORMAT_RED } from "./cliFormat";
|
|
11
11
|
|
|
12
|
-
export function testProject(
|
|
12
|
+
export async function testProject(
|
|
13
|
+
rootDirectoryPath: string,
|
|
14
|
+
projectConfig: ProjectConfig,
|
|
15
|
+
): Promise<boolean> {
|
|
13
16
|
let hasError = false;
|
|
14
17
|
const datasource = new Datasource(projectConfig);
|
|
15
18
|
|
|
@@ -20,7 +23,7 @@ export function testProject(rootDirectoryPath: string, projectConfig: ProjectCon
|
|
|
20
23
|
return hasError;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
const testFiles = datasource.listTests();
|
|
26
|
+
const testFiles = await datasource.listTests();
|
|
24
27
|
|
|
25
28
|
if (testFiles.length === 0) {
|
|
26
29
|
console.error(`No tests found in: ${projectConfig.testsDirectoryPath}`);
|
|
@@ -35,13 +38,13 @@ export function testProject(rootDirectoryPath: string, projectConfig: ProjectCon
|
|
|
35
38
|
console.log("");
|
|
36
39
|
console.log(CLI_FORMAT_BOLD, `Testing: ${testFilePath.replace(rootDirectoryPath, "")}`);
|
|
37
40
|
|
|
38
|
-
const t = datasource.readTest(testFile);
|
|
41
|
+
const t = await datasource.readTest(testFile);
|
|
39
42
|
|
|
40
43
|
if ((t as TestSegment).segment) {
|
|
41
44
|
// segment testing
|
|
42
45
|
const test = t as TestSegment;
|
|
43
46
|
|
|
44
|
-
const segmentHasError = testSegment(datasource, test);
|
|
47
|
+
const segmentHasError = await testSegment(datasource, test);
|
|
45
48
|
|
|
46
49
|
if (segmentHasError) {
|
|
47
50
|
hasError = true;
|
|
@@ -50,7 +53,7 @@ export function testProject(rootDirectoryPath: string, projectConfig: ProjectCon
|
|
|
50
53
|
// feature testing
|
|
51
54
|
const test = t as TestFeature;
|
|
52
55
|
|
|
53
|
-
const featureHasError = testFeature(datasource, projectConfig, test);
|
|
56
|
+
const featureHasError = await testFeature(datasource, projectConfig, test);
|
|
54
57
|
|
|
55
58
|
if (featureHasError) {
|
|
56
59
|
hasError = true;
|
|
@@ -5,14 +5,14 @@ import { Datasource } from "../datasource";
|
|
|
5
5
|
|
|
6
6
|
import { CLI_FORMAT_BOLD, CLI_FORMAT_RED } from "./cliFormat";
|
|
7
7
|
|
|
8
|
-
export function testSegment(datasource: Datasource, test: TestSegment): boolean {
|
|
8
|
+
export async function testSegment(datasource: Datasource, test: TestSegment): Promise<boolean> {
|
|
9
9
|
let hasError = false;
|
|
10
10
|
|
|
11
11
|
const segmentKey = test.segment;
|
|
12
12
|
|
|
13
13
|
console.log(CLI_FORMAT_BOLD, ` Segment "${segmentKey}":`);
|
|
14
14
|
|
|
15
|
-
const segmentExists = datasource.entityExists("segment", segmentKey);
|
|
15
|
+
const segmentExists = await datasource.entityExists("segment", segmentKey);
|
|
16
16
|
|
|
17
17
|
if (!segmentExists) {
|
|
18
18
|
console.error(CLI_FORMAT_RED, ` Segment does not exist: ${segmentKey}`);
|
|
@@ -21,7 +21,7 @@ export function testSegment(datasource: Datasource, test: TestSegment): boolean
|
|
|
21
21
|
return hasError;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const parsedSegment = datasource.readSegment(segmentKey);
|
|
24
|
+
const parsedSegment = await datasource.readSegment(segmentKey);
|
|
25
25
|
const conditions = parsedSegment.conditions as Condition | Condition[];
|
|
26
26
|
|
|
27
27
|
test.assertions.forEach(function (assertion, aIndex) {
|
package/src/utils.ts
CHANGED
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
|
|
4
|
-
import * as yaml from "js-yaml";
|
|
5
|
-
|
|
6
1
|
import { Condition, AttributeKey, GroupSegment, SegmentKey } from "@featurevisor/types";
|
|
7
2
|
|
|
8
|
-
export function getYAMLFiles(directoryPath: string) {
|
|
9
|
-
const files = fs.readdirSync(directoryPath);
|
|
10
|
-
const yamlFiles = files.filter((file) => file.endsWith(".yml"));
|
|
11
|
-
|
|
12
|
-
return yamlFiles.map((file) => path.join(directoryPath, file));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function parseYaml(content: string) {
|
|
16
|
-
const parsed = yaml.load(content);
|
|
17
|
-
|
|
18
|
-
return parsed;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
3
|
export function extractSegmentKeysFromGroupSegments(
|
|
22
4
|
segments: GroupSegment | GroupSegment[],
|
|
23
5
|
): Set<SegmentKey> {
|