This repository has been archived by the owner on May 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathevaluator_helpers.js
106 lines (94 loc) · 2.92 KB
/
evaluator_helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const { EventFactory } = require('../event_factory');
// All three of these users should represent the same user.
const basicUser = { key: 'userkey' };
const basicSingleKindUser = { kind: 'user', key: 'userkey' };
const basicMultiKindUser = { kind: 'multi', user: { key: 'userkey' } };
const eventFactory = EventFactory(false);
// Evaluator.evaluate uses a callback instead of a promise because it's a slightly more efficient
// way to pass multiple return values. But for the purposes of our tests, it's much easier to use
// a promise and async/await, so we'll transform it with this helper. Unlike usual Node promise
// semantics, here we treat "err" as just another return parameter rather than throwing an error
// (because the other parameters can still be non-null even if there's an error).
function asyncEvaluate(evaluator, flag, user, eventFactory) {
return new Promise(resolve => {
evaluator.evaluate(flag, user, eventFactory, (err, detail, events) => resolve([err, detail, events]));
});
}
function makeFlagWithRules(rules, fallthrough) {
if (!fallthrough) {
fallthrough = { variation: 0 };
}
return {
key: 'feature',
on: true,
rules: rules,
targets: [],
fallthrough: fallthrough,
offVariation: 1,
variations: ['a', 'b', 'c']
};
}
function makeBooleanFlagWithRules(rules) {
return {
key: 'feature',
on: true,
prerequisites: [],
rules: rules,
targets: [],
salt: '',
fallthrough: { variation: 0 },
offVariation: 0,
variations: [false, true],
version: 1
};
}
function makeBooleanFlagWithOneClause(clause) {
return makeBooleanFlagWithRules([{ clauses: [clause], variation: 1 }]);
}
function makeFlagWithSegmentMatch(segment) {
return makeBooleanFlagWithOneClause(makeSegmentMatchClause(segment));
}
function makeClauseThatMatchesUser(user) {
return { attribute: 'key', op: 'in', values: [user.key] };
}
function makeClauseThatDoesNotMatchUser(user) {
return { attribute: 'key', op: 'in', values: ['not-' + user.key] };
}
function makeSegmentMatchClause(segment) {
return { attribute: '', op: 'segmentMatch', values: [segment.key] };
}
function prepareQueries(data) {
let flagsMap = {}, segmentsMap = {};
for (const f of (data.flags || [])) {
flagsMap[f.key] = f;
}
for (const s of (data.segments || [])) {
segmentsMap[s.key] = s;
}
return {
getFlag: (key, cb) => cb(flagsMap[key]),
getSegment: (key, cb) => cb(segmentsMap[key]),
getBigSegmentsMembership: (key, cb) => {
if (data.bigSegments) {
cb([data.bigSegments[key], 'HEALTHY']);
} else {
cb(null);
}
},
};
}
module.exports = {
basicUser,
basicSingleKindUser,
basicMultiKindUser,
eventFactory,
asyncEvaluate,
makeFlagWithRules,
makeBooleanFlagWithRules,
makeBooleanFlagWithOneClause,
makeFlagWithSegmentMatch,
makeClauseThatMatchesUser,
makeClauseThatDoesNotMatchUser,
makeSegmentMatchClause,
prepareQueries,
};