@featurevisor/sdk 1.2.3 → 1.11.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/.eslintcache +1 -1
- package/CHANGELOG.md +19 -0
- package/coverage/clover.xml +325 -322
- package/coverage/coverage-final.json +5 -5
- package/coverage/lcov-report/bucket.ts.html +1 -1
- package/coverage/lcov-report/conditions.ts.html +58 -10
- package/coverage/lcov-report/datafileReader.ts.html +1 -1
- package/coverage/lcov-report/emitter.ts.html +1 -1
- package/coverage/lcov-report/feature.ts.html +35 -5
- package/coverage/lcov-report/index.html +11 -11
- package/coverage/lcov-report/instance.ts.html +33 -6
- package/coverage/lcov-report/logger.ts.html +11 -11
- package/coverage/lcov-report/segments.ts.html +15 -9
- package/coverage/lcov.info +575 -572
- package/dist/index.js +1 -1
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/lib/conditions.d.ts +2 -1
- package/lib/conditions.js +18 -6
- package/lib/conditions.js.map +1 -1
- package/lib/feature.d.ts +4 -3
- package/lib/feature.js +7 -7
- package/lib/feature.js.map +1 -1
- package/lib/instance.js +8 -8
- package/lib/instance.js.map +1 -1
- package/lib/segments.d.ts +3 -2
- package/lib/segments.js +8 -8
- package/lib/segments.js.map +1 -1
- package/package.json +3 -3
- package/src/conditions.spec.ts +358 -192
- package/src/conditions.ts +20 -4
- package/src/feature.ts +13 -3
- package/src/instance.ts +13 -4
- package/src/segments.spec.ts +56 -28
- package/src/segments.ts +9 -7
package/src/conditions.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { compareVersions } from "compare-versions";
|
|
|
2
2
|
|
|
3
3
|
import { Context, Condition, PlainCondition } from "@featurevisor/types";
|
|
4
4
|
|
|
5
|
+
import { Logger } from "./logger";
|
|
6
|
+
|
|
5
7
|
export function conditionIsMatched(condition: PlainCondition, context: Context): boolean {
|
|
6
8
|
const { attribute, operator, value } = condition;
|
|
7
9
|
|
|
@@ -75,17 +77,30 @@ export function conditionIsMatched(condition: PlainCondition, context: Context):
|
|
|
75
77
|
export function allConditionsAreMatched(
|
|
76
78
|
conditions: Condition[] | Condition,
|
|
77
79
|
context: Context,
|
|
80
|
+
logger: Logger,
|
|
78
81
|
): boolean {
|
|
79
82
|
if ("attribute" in conditions) {
|
|
80
|
-
|
|
83
|
+
try {
|
|
84
|
+
return conditionIsMatched(conditions, context);
|
|
85
|
+
} catch (e) {
|
|
86
|
+
logger.warn(e.message, {
|
|
87
|
+
error: e,
|
|
88
|
+
details: {
|
|
89
|
+
condition: conditions,
|
|
90
|
+
context,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
if ("and" in conditions && Array.isArray(conditions.and)) {
|
|
84
|
-
return conditions.and.every((c) => allConditionsAreMatched(c, context));
|
|
99
|
+
return conditions.and.every((c) => allConditionsAreMatched(c, context, logger));
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
if ("or" in conditions && Array.isArray(conditions.or)) {
|
|
88
|
-
return conditions.or.some((c) => allConditionsAreMatched(c, context));
|
|
103
|
+
return conditions.or.some((c) => allConditionsAreMatched(c, context, logger));
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
if ("not" in conditions && Array.isArray(conditions.not)) {
|
|
@@ -96,12 +111,13 @@ export function allConditionsAreMatched(
|
|
|
96
111
|
and: conditions.not,
|
|
97
112
|
},
|
|
98
113
|
context,
|
|
114
|
+
logger,
|
|
99
115
|
) === false,
|
|
100
116
|
);
|
|
101
117
|
}
|
|
102
118
|
|
|
103
119
|
if (Array.isArray(conditions)) {
|
|
104
|
-
return conditions.every((c) => allConditionsAreMatched(c, context));
|
|
120
|
+
return conditions.every((c) => allConditionsAreMatched(c, context, logger));
|
|
105
121
|
}
|
|
106
122
|
|
|
107
123
|
return false;
|
package/src/feature.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Allocation, Context, Traffic, Feature, Force } from "@featurevisor/type
|
|
|
2
2
|
import { DatafileReader } from "./datafileReader";
|
|
3
3
|
import { allGroupSegmentsAreMatched } from "./segments";
|
|
4
4
|
import { allConditionsAreMatched } from "./conditions";
|
|
5
|
+
import { Logger } from "./logger";
|
|
5
6
|
|
|
6
7
|
export function getMatchedAllocation(
|
|
7
8
|
traffic: Traffic,
|
|
@@ -30,10 +31,16 @@ export function getMatchedTraffic(
|
|
|
30
31
|
traffic: Traffic[],
|
|
31
32
|
context: Context,
|
|
32
33
|
datafileReader: DatafileReader,
|
|
34
|
+
logger: Logger,
|
|
33
35
|
): Traffic | undefined {
|
|
34
36
|
return traffic.find((t) => {
|
|
35
37
|
if (
|
|
36
|
-
!allGroupSegmentsAreMatched(
|
|
38
|
+
!allGroupSegmentsAreMatched(
|
|
39
|
+
parseFromStringifiedSegments(t.segments),
|
|
40
|
+
context,
|
|
41
|
+
datafileReader,
|
|
42
|
+
logger,
|
|
43
|
+
)
|
|
37
44
|
) {
|
|
38
45
|
return false;
|
|
39
46
|
}
|
|
@@ -52,12 +59,14 @@ export function getMatchedTrafficAndAllocation(
|
|
|
52
59
|
context: Context,
|
|
53
60
|
bucketValue: number,
|
|
54
61
|
datafileReader: DatafileReader,
|
|
62
|
+
logger: Logger,
|
|
55
63
|
): MatchedTrafficAndAllocation {
|
|
56
64
|
const matchedTraffic = traffic.find((t) => {
|
|
57
65
|
return allGroupSegmentsAreMatched(
|
|
58
66
|
parseFromStringifiedSegments(t.segments),
|
|
59
67
|
context,
|
|
60
68
|
datafileReader,
|
|
69
|
+
logger,
|
|
61
70
|
);
|
|
62
71
|
});
|
|
63
72
|
|
|
@@ -80,6 +89,7 @@ export function findForceFromFeature(
|
|
|
80
89
|
feature: Feature,
|
|
81
90
|
context: Context,
|
|
82
91
|
datafileReader: DatafileReader,
|
|
92
|
+
logger: Logger,
|
|
83
93
|
): Force | undefined {
|
|
84
94
|
if (!feature.force) {
|
|
85
95
|
return undefined;
|
|
@@ -87,11 +97,11 @@ export function findForceFromFeature(
|
|
|
87
97
|
|
|
88
98
|
return feature.force.find((f: Force) => {
|
|
89
99
|
if (f.conditions) {
|
|
90
|
-
return allConditionsAreMatched(f.conditions, context);
|
|
100
|
+
return allConditionsAreMatched(f.conditions, context, logger);
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
if (f.segments) {
|
|
94
|
-
return allGroupSegmentsAreMatched(f.segments, context, datafileReader);
|
|
104
|
+
return allGroupSegmentsAreMatched(f.segments, context, datafileReader, logger);
|
|
95
105
|
}
|
|
96
106
|
|
|
97
107
|
return false;
|
package/src/instance.ts
CHANGED
|
@@ -521,7 +521,7 @@ export class FeaturevisorInstance {
|
|
|
521
521
|
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
522
522
|
|
|
523
523
|
// forced
|
|
524
|
-
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
524
|
+
const force = findForceFromFeature(feature, context, this.datafileReader, this.logger);
|
|
525
525
|
|
|
526
526
|
if (force && typeof force.enabled !== "undefined") {
|
|
527
527
|
evaluation = {
|
|
@@ -579,7 +579,12 @@ export class FeaturevisorInstance {
|
|
|
579
579
|
// bucketing
|
|
580
580
|
const bucketValue = this.getBucketValue(feature, finalContext);
|
|
581
581
|
|
|
582
|
-
const matchedTraffic = getMatchedTraffic(
|
|
582
|
+
const matchedTraffic = getMatchedTraffic(
|
|
583
|
+
feature.traffic,
|
|
584
|
+
finalContext,
|
|
585
|
+
this.datafileReader,
|
|
586
|
+
this.logger,
|
|
587
|
+
);
|
|
583
588
|
|
|
584
589
|
if (matchedTraffic) {
|
|
585
590
|
// check if mutually exclusive
|
|
@@ -774,7 +779,7 @@ export class FeaturevisorInstance {
|
|
|
774
779
|
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
775
780
|
|
|
776
781
|
// forced
|
|
777
|
-
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
782
|
+
const force = findForceFromFeature(feature, context, this.datafileReader, this.logger);
|
|
778
783
|
|
|
779
784
|
if (force && force.variation) {
|
|
780
785
|
const variation = feature.variations.find((v) => v.value === force.variation);
|
|
@@ -800,6 +805,7 @@ export class FeaturevisorInstance {
|
|
|
800
805
|
finalContext,
|
|
801
806
|
bucketValue,
|
|
802
807
|
this.datafileReader,
|
|
808
|
+
this.logger,
|
|
803
809
|
);
|
|
804
810
|
|
|
805
811
|
if (matchedTraffic) {
|
|
@@ -1040,7 +1046,7 @@ export class FeaturevisorInstance {
|
|
|
1040
1046
|
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
1041
1047
|
|
|
1042
1048
|
// forced
|
|
1043
|
-
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
1049
|
+
const force = findForceFromFeature(feature, context, this.datafileReader, this.logger);
|
|
1044
1050
|
|
|
1045
1051
|
if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {
|
|
1046
1052
|
evaluation = {
|
|
@@ -1064,6 +1070,7 @@ export class FeaturevisorInstance {
|
|
|
1064
1070
|
finalContext,
|
|
1065
1071
|
bucketValue,
|
|
1066
1072
|
this.datafileReader,
|
|
1073
|
+
this.logger,
|
|
1067
1074
|
);
|
|
1068
1075
|
|
|
1069
1076
|
if (matchedTraffic) {
|
|
@@ -1109,6 +1116,7 @@ export class FeaturevisorInstance {
|
|
|
1109
1116
|
return allConditionsAreMatched(
|
|
1110
1117
|
typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
|
|
1111
1118
|
finalContext,
|
|
1119
|
+
this.logger,
|
|
1112
1120
|
);
|
|
1113
1121
|
}
|
|
1114
1122
|
|
|
@@ -1117,6 +1125,7 @@ export class FeaturevisorInstance {
|
|
|
1117
1125
|
parseFromStringifiedSegments(o.segments),
|
|
1118
1126
|
finalContext,
|
|
1119
1127
|
this.datafileReader,
|
|
1128
|
+
this.logger,
|
|
1120
1129
|
);
|
|
1121
1130
|
}
|
|
1122
1131
|
|
package/src/segments.spec.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { DatafileContent, GroupSegment } from "@featurevisor/types";
|
|
2
|
+
|
|
1
3
|
import { DatafileReader } from "./datafileReader";
|
|
2
4
|
import { allGroupSegmentsAreMatched } from "./segments";
|
|
3
|
-
import {
|
|
5
|
+
import { createLogger } from "./logger";
|
|
4
6
|
|
|
5
7
|
interface Group {
|
|
6
8
|
key: string;
|
|
@@ -8,6 +10,8 @@ interface Group {
|
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
describe("sdk: Segments", function () {
|
|
13
|
+
const logger = createLogger();
|
|
14
|
+
|
|
11
15
|
it("should be a function", function () {
|
|
12
16
|
expect(typeof allGroupSegmentsAreMatched).toEqual("function");
|
|
13
17
|
});
|
|
@@ -178,13 +182,13 @@ describe("sdk: Segments", function () {
|
|
|
178
182
|
const group = groups.find((g) => g.key === "*") as Group;
|
|
179
183
|
|
|
180
184
|
// match
|
|
181
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(true);
|
|
182
|
-
expect(
|
|
183
|
-
|
|
184
|
-
);
|
|
185
|
-
expect(
|
|
186
|
-
|
|
187
|
-
);
|
|
185
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(true);
|
|
186
|
+
expect(
|
|
187
|
+
allGroupSegmentsAreMatched(group.segments, { foo: "foo" }, datafileReader, logger),
|
|
188
|
+
).toEqual(true);
|
|
189
|
+
expect(
|
|
190
|
+
allGroupSegmentsAreMatched(group.segments, { bar: "bar" }, datafileReader, logger),
|
|
191
|
+
).toEqual(true);
|
|
188
192
|
});
|
|
189
193
|
|
|
190
194
|
it("should match dutchMobileUsers", function () {
|
|
@@ -196,6 +200,7 @@ describe("sdk: Segments", function () {
|
|
|
196
200
|
group.segments,
|
|
197
201
|
{ country: "nl", deviceType: "mobile" },
|
|
198
202
|
datafileReader,
|
|
203
|
+
logger,
|
|
199
204
|
),
|
|
200
205
|
).toEqual(true);
|
|
201
206
|
expect(
|
|
@@ -203,16 +208,18 @@ describe("sdk: Segments", function () {
|
|
|
203
208
|
group.segments,
|
|
204
209
|
{ country: "nl", deviceType: "mobile", browser: "chrome" },
|
|
205
210
|
datafileReader,
|
|
211
|
+
logger,
|
|
206
212
|
),
|
|
207
213
|
).toEqual(true);
|
|
208
214
|
|
|
209
215
|
// not match
|
|
210
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
216
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
211
217
|
expect(
|
|
212
218
|
allGroupSegmentsAreMatched(
|
|
213
219
|
group.segments,
|
|
214
220
|
{ country: "de", deviceType: "mobile" },
|
|
215
221
|
datafileReader,
|
|
222
|
+
logger,
|
|
216
223
|
),
|
|
217
224
|
).toEqual(false);
|
|
218
225
|
});
|
|
@@ -226,6 +233,7 @@ describe("sdk: Segments", function () {
|
|
|
226
233
|
group.segments,
|
|
227
234
|
{ country: "nl", deviceType: "mobile" },
|
|
228
235
|
datafileReader,
|
|
236
|
+
logger,
|
|
229
237
|
),
|
|
230
238
|
).toEqual(true);
|
|
231
239
|
expect(
|
|
@@ -233,16 +241,18 @@ describe("sdk: Segments", function () {
|
|
|
233
241
|
group.segments,
|
|
234
242
|
{ country: "nl", deviceType: "mobile", browser: "chrome" },
|
|
235
243
|
datafileReader,
|
|
244
|
+
logger,
|
|
236
245
|
),
|
|
237
246
|
).toEqual(true);
|
|
238
247
|
|
|
239
248
|
// not match
|
|
240
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
249
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
241
250
|
expect(
|
|
242
251
|
allGroupSegmentsAreMatched(
|
|
243
252
|
group.segments,
|
|
244
253
|
{ country: "de", deviceType: "mobile" },
|
|
245
254
|
datafileReader,
|
|
255
|
+
logger,
|
|
246
256
|
),
|
|
247
257
|
).toEqual(false);
|
|
248
258
|
});
|
|
@@ -256,6 +266,7 @@ describe("sdk: Segments", function () {
|
|
|
256
266
|
group.segments,
|
|
257
267
|
{ country: "nl", deviceType: "mobile" },
|
|
258
268
|
datafileReader,
|
|
269
|
+
logger,
|
|
259
270
|
),
|
|
260
271
|
).toEqual(true);
|
|
261
272
|
expect(
|
|
@@ -263,6 +274,7 @@ describe("sdk: Segments", function () {
|
|
|
263
274
|
group.segments,
|
|
264
275
|
{ country: "nl", deviceType: "mobile", browser: "chrome" },
|
|
265
276
|
datafileReader,
|
|
277
|
+
logger,
|
|
266
278
|
),
|
|
267
279
|
).toEqual(true);
|
|
268
280
|
expect(
|
|
@@ -270,6 +282,7 @@ describe("sdk: Segments", function () {
|
|
|
270
282
|
group.segments,
|
|
271
283
|
{ country: "nl", deviceType: "desktop" },
|
|
272
284
|
datafileReader,
|
|
285
|
+
logger,
|
|
273
286
|
),
|
|
274
287
|
).toEqual(true);
|
|
275
288
|
expect(
|
|
@@ -277,16 +290,18 @@ describe("sdk: Segments", function () {
|
|
|
277
290
|
group.segments,
|
|
278
291
|
{ country: "nl", deviceType: "desktop", browser: "chrome" },
|
|
279
292
|
datafileReader,
|
|
293
|
+
logger,
|
|
280
294
|
),
|
|
281
295
|
).toEqual(true);
|
|
282
296
|
|
|
283
297
|
// not match
|
|
284
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
298
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
285
299
|
expect(
|
|
286
300
|
allGroupSegmentsAreMatched(
|
|
287
301
|
group.segments,
|
|
288
302
|
{ country: "de", deviceType: "mobile" },
|
|
289
303
|
datafileReader,
|
|
304
|
+
logger,
|
|
290
305
|
),
|
|
291
306
|
).toEqual(false);
|
|
292
307
|
expect(
|
|
@@ -294,6 +309,7 @@ describe("sdk: Segments", function () {
|
|
|
294
309
|
group.segments,
|
|
295
310
|
{ country: "de", deviceType: "desktop" },
|
|
296
311
|
datafileReader,
|
|
312
|
+
logger,
|
|
297
313
|
),
|
|
298
314
|
).toEqual(false);
|
|
299
315
|
});
|
|
@@ -307,6 +323,7 @@ describe("sdk: Segments", function () {
|
|
|
307
323
|
group.segments,
|
|
308
324
|
{ country: "nl", deviceType: "mobile" },
|
|
309
325
|
datafileReader,
|
|
326
|
+
logger,
|
|
310
327
|
),
|
|
311
328
|
).toEqual(true);
|
|
312
329
|
expect(
|
|
@@ -314,6 +331,7 @@ describe("sdk: Segments", function () {
|
|
|
314
331
|
group.segments,
|
|
315
332
|
{ country: "nl", deviceType: "mobile", browser: "chrome" },
|
|
316
333
|
datafileReader,
|
|
334
|
+
logger,
|
|
317
335
|
),
|
|
318
336
|
).toEqual(true);
|
|
319
337
|
expect(
|
|
@@ -321,6 +339,7 @@ describe("sdk: Segments", function () {
|
|
|
321
339
|
group.segments,
|
|
322
340
|
{ country: "nl", deviceType: "desktop" },
|
|
323
341
|
datafileReader,
|
|
342
|
+
logger,
|
|
324
343
|
),
|
|
325
344
|
).toEqual(true);
|
|
326
345
|
expect(
|
|
@@ -328,16 +347,18 @@ describe("sdk: Segments", function () {
|
|
|
328
347
|
group.segments,
|
|
329
348
|
{ country: "nl", deviceType: "desktop", browser: "chrome" },
|
|
330
349
|
datafileReader,
|
|
350
|
+
logger,
|
|
331
351
|
),
|
|
332
352
|
).toEqual(true);
|
|
333
353
|
|
|
334
354
|
// not match
|
|
335
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
355
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
336
356
|
expect(
|
|
337
357
|
allGroupSegmentsAreMatched(
|
|
338
358
|
group.segments,
|
|
339
359
|
{ country: "de", deviceType: "mobile" },
|
|
340
360
|
datafileReader,
|
|
361
|
+
logger,
|
|
341
362
|
),
|
|
342
363
|
).toEqual(false);
|
|
343
364
|
expect(
|
|
@@ -345,6 +366,7 @@ describe("sdk: Segments", function () {
|
|
|
345
366
|
group.segments,
|
|
346
367
|
{ country: "de", deviceType: "desktop" },
|
|
347
368
|
datafileReader,
|
|
369
|
+
logger,
|
|
348
370
|
),
|
|
349
371
|
).toEqual(false);
|
|
350
372
|
});
|
|
@@ -358,6 +380,7 @@ describe("sdk: Segments", function () {
|
|
|
358
380
|
group.segments,
|
|
359
381
|
{ country: "de", deviceType: "mobile" },
|
|
360
382
|
datafileReader,
|
|
383
|
+
logger,
|
|
361
384
|
),
|
|
362
385
|
).toEqual(true);
|
|
363
386
|
expect(
|
|
@@ -365,16 +388,18 @@ describe("sdk: Segments", function () {
|
|
|
365
388
|
group.segments,
|
|
366
389
|
{ country: "de", deviceType: "mobile", browser: "chrome" },
|
|
367
390
|
datafileReader,
|
|
391
|
+
logger,
|
|
368
392
|
),
|
|
369
393
|
).toEqual(true);
|
|
370
394
|
|
|
371
395
|
// not match
|
|
372
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
396
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
373
397
|
expect(
|
|
374
398
|
allGroupSegmentsAreMatched(
|
|
375
399
|
group.segments,
|
|
376
400
|
{ country: "nl", deviceType: "mobile" },
|
|
377
401
|
datafileReader,
|
|
402
|
+
logger,
|
|
378
403
|
),
|
|
379
404
|
).toEqual(false);
|
|
380
405
|
});
|
|
@@ -388,6 +413,7 @@ describe("sdk: Segments", function () {
|
|
|
388
413
|
group.segments,
|
|
389
414
|
{ country: "de", deviceType: "desktop" },
|
|
390
415
|
datafileReader,
|
|
416
|
+
logger,
|
|
391
417
|
),
|
|
392
418
|
).toEqual(true);
|
|
393
419
|
expect(
|
|
@@ -395,16 +421,18 @@ describe("sdk: Segments", function () {
|
|
|
395
421
|
group.segments,
|
|
396
422
|
{ country: "de", deviceType: "desktop", browser: "chrome" },
|
|
397
423
|
datafileReader,
|
|
424
|
+
logger,
|
|
398
425
|
),
|
|
399
426
|
).toEqual(true);
|
|
400
427
|
|
|
401
428
|
// not match
|
|
402
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(false);
|
|
429
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(false);
|
|
403
430
|
expect(
|
|
404
431
|
allGroupSegmentsAreMatched(
|
|
405
432
|
group.segments,
|
|
406
433
|
{ country: "nl", deviceType: "desktop" },
|
|
407
434
|
datafileReader,
|
|
435
|
+
logger,
|
|
408
436
|
),
|
|
409
437
|
).toEqual(false);
|
|
410
438
|
});
|
|
@@ -413,28 +441,28 @@ describe("sdk: Segments", function () {
|
|
|
413
441
|
const group = groups.find((g) => g.key === "notVersion5.5") as Group;
|
|
414
442
|
|
|
415
443
|
// match
|
|
416
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(true);
|
|
417
|
-
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader)).toEqual(true);
|
|
444
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(true);
|
|
445
|
+
expect(allGroupSegmentsAreMatched(group.segments, {}, datafileReader, logger)).toEqual(true);
|
|
446
|
+
expect(
|
|
447
|
+
allGroupSegmentsAreMatched(group.segments, { version: "5.6" }, datafileReader, logger),
|
|
448
|
+
).toEqual(true);
|
|
418
449
|
expect(
|
|
419
|
-
allGroupSegmentsAreMatched(group.segments, { version:
|
|
450
|
+
allGroupSegmentsAreMatched(group.segments, { version: 5.6 }, datafileReader, logger),
|
|
420
451
|
).toEqual(true);
|
|
421
|
-
expect(allGroupSegmentsAreMatched(group.segments, { version: 5.6 }, datafileReader)).toEqual(
|
|
422
|
-
true,
|
|
423
|
-
);
|
|
424
452
|
expect(
|
|
425
|
-
allGroupSegmentsAreMatched(group.segments, { version: "5.7" }, datafileReader),
|
|
453
|
+
allGroupSegmentsAreMatched(group.segments, { version: "5.7" }, datafileReader, logger),
|
|
454
|
+
).toEqual(true);
|
|
455
|
+
expect(
|
|
456
|
+
allGroupSegmentsAreMatched(group.segments, { version: 5.7 }, datafileReader, logger),
|
|
426
457
|
).toEqual(true);
|
|
427
|
-
expect(allGroupSegmentsAreMatched(group.segments, { version: 5.7 }, datafileReader)).toEqual(
|
|
428
|
-
true,
|
|
429
|
-
);
|
|
430
458
|
|
|
431
459
|
// not match
|
|
432
460
|
expect(
|
|
433
|
-
allGroupSegmentsAreMatched(group.segments, { version: "5.5" }, datafileReader),
|
|
461
|
+
allGroupSegmentsAreMatched(group.segments, { version: "5.5" }, datafileReader, logger),
|
|
462
|
+
).toEqual(false);
|
|
463
|
+
expect(
|
|
464
|
+
allGroupSegmentsAreMatched(group.segments, { version: 5.5 }, datafileReader, logger),
|
|
434
465
|
).toEqual(false);
|
|
435
|
-
expect(allGroupSegmentsAreMatched(group.segments, { version: 5.5 }, datafileReader)).toEqual(
|
|
436
|
-
false,
|
|
437
|
-
);
|
|
438
466
|
});
|
|
439
467
|
});
|
|
440
468
|
});
|
package/src/segments.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Context, GroupSegment, Segment, Condition } from "@featurevisor/types";
|
|
2
2
|
import { allConditionsAreMatched } from "./conditions";
|
|
3
3
|
import { DatafileReader } from "./datafileReader";
|
|
4
|
+
import { Logger } from "./logger";
|
|
4
5
|
|
|
5
|
-
export function segmentIsMatched(segment: Segment, context: Context): boolean {
|
|
6
|
-
return allConditionsAreMatched(segment.conditions as Condition | Condition[], context);
|
|
6
|
+
export function segmentIsMatched(segment: Segment, context: Context, logger: Logger): boolean {
|
|
7
|
+
return allConditionsAreMatched(segment.conditions as Condition | Condition[], context, logger);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export function allGroupSegmentsAreMatched(
|
|
10
11
|
groupSegments: GroupSegment | GroupSegment[] | "*",
|
|
11
12
|
context: Context,
|
|
12
13
|
datafileReader: DatafileReader,
|
|
14
|
+
logger: Logger,
|
|
13
15
|
): boolean {
|
|
14
16
|
if (groupSegments === "*") {
|
|
15
17
|
return true;
|
|
@@ -19,7 +21,7 @@ export function allGroupSegmentsAreMatched(
|
|
|
19
21
|
const segment = datafileReader.getSegment(groupSegments);
|
|
20
22
|
|
|
21
23
|
if (segment) {
|
|
22
|
-
return segmentIsMatched(segment, context);
|
|
24
|
+
return segmentIsMatched(segment, context, logger);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
return false;
|
|
@@ -28,27 +30,27 @@ export function allGroupSegmentsAreMatched(
|
|
|
28
30
|
if (typeof groupSegments === "object") {
|
|
29
31
|
if ("and" in groupSegments && Array.isArray(groupSegments.and)) {
|
|
30
32
|
return groupSegments.and.every((groupSegment) =>
|
|
31
|
-
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
|
|
33
|
+
allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),
|
|
32
34
|
);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
if ("or" in groupSegments && Array.isArray(groupSegments.or)) {
|
|
36
38
|
return groupSegments.or.some((groupSegment) =>
|
|
37
|
-
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
|
|
39
|
+
allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),
|
|
38
40
|
);
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
if ("not" in groupSegments && Array.isArray(groupSegments.not)) {
|
|
42
44
|
return groupSegments.not.every(
|
|
43
45
|
(groupSegment) =>
|
|
44
|
-
allGroupSegmentsAreMatched(groupSegment, context, datafileReader) === false,
|
|
46
|
+
allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger) === false,
|
|
45
47
|
);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
if (Array.isArray(groupSegments)) {
|
|
50
52
|
return groupSegments.every((groupSegment) =>
|
|
51
|
-
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
|
|
53
|
+
allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),
|
|
52
54
|
);
|
|
53
55
|
}
|
|
54
56
|
|