Skip to content

Commit 8cf223e

Browse files
committed
More cleanup
1 parent 311766e commit 8cf223e

File tree

3 files changed

+100
-4
lines changed

3 files changed

+100
-4
lines changed

packages/vercel-flags-core/src/evaluate.test.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,94 @@ describe('evaluate', () => {
18131813
entities: { user: { id: null } },
18141814
result: false,
18151815
},
1816+
1817+
// ---- ci flag is ignored for non-string comparators ----
1818+
1819+
{
1820+
name: `${Comparator.EXISTS} ci ignored (still matches)`,
1821+
condition: [['user', 'id'], Comparator.EXISTS, undefined, { ci: true }],
1822+
entities: { user: { id: 'uid1' } },
1823+
result: true,
1824+
},
1825+
{
1826+
name: `${Comparator.NOT_EXISTS} ci ignored (still matches)`,
1827+
condition: [
1828+
['user', 'id'],
1829+
Comparator.NOT_EXISTS,
1830+
undefined,
1831+
{ ci: true },
1832+
],
1833+
entities: { user: {} },
1834+
result: true,
1835+
},
1836+
{
1837+
name: `${Comparator.GT} ci ignored (numeric comparison unchanged)`,
1838+
condition: [['user', 'age'], Comparator.GT, 20, { ci: true }],
1839+
entities: { user: { age: 30 } },
1840+
result: true,
1841+
},
1842+
{
1843+
name: `${Comparator.LT} ci ignored (numeric comparison unchanged)`,
1844+
condition: [['user', 'age'], Comparator.LT, 40, { ci: true }],
1845+
entities: { user: { age: 30 } },
1846+
result: true,
1847+
},
1848+
{
1849+
name: `${Comparator.GTE} ci ignored (numeric comparison unchanged)`,
1850+
condition: [['user', 'age'], Comparator.GTE, 30, { ci: true }],
1851+
entities: { user: { age: 30 } },
1852+
result: true,
1853+
},
1854+
{
1855+
name: `${Comparator.LTE} ci ignored (numeric comparison unchanged)`,
1856+
condition: [['user', 'age'], Comparator.LTE, 30, { ci: true }],
1857+
entities: { user: { age: 30 } },
1858+
result: true,
1859+
},
1860+
{
1861+
name: `${Comparator.REGEX} ci ignored (uses raw values)`,
1862+
condition: [
1863+
['user', 'id'],
1864+
Comparator.REGEX,
1865+
{ type: 'regex', pattern: '^joe', flags: '' },
1866+
{ ci: true },
1867+
],
1868+
entities: { user: { id: 'joewilkinson' } },
1869+
result: true,
1870+
},
1871+
{
1872+
name: `${Comparator.NOT_REGEX} ci ignored (uses raw values)`,
1873+
condition: [
1874+
['user', 'id'],
1875+
Comparator.NOT_REGEX,
1876+
{ type: 'regex', pattern: '^joe', flags: '' },
1877+
{ ci: true },
1878+
],
1879+
entities: { user: { id: 'joewilkinson' } },
1880+
result: false,
1881+
},
1882+
{
1883+
name: `${Comparator.BEFORE} ci ignored (date comparison unchanged)`,
1884+
condition: [
1885+
['user', 'createdAt'],
1886+
Comparator.BEFORE,
1887+
'2025-01-02',
1888+
{ ci: true },
1889+
],
1890+
entities: { user: { createdAt: '2025-01-01' } },
1891+
result: true,
1892+
},
1893+
{
1894+
name: `${Comparator.AFTER} ci ignored (date comparison unchanged)`,
1895+
condition: [
1896+
['user', 'createdAt'],
1897+
Comparator.AFTER,
1898+
'2024-12-31',
1899+
{ ci: true },
1900+
],
1901+
entities: { user: { createdAt: '2025-01-01' } },
1902+
result: true,
1903+
},
18161904
])('should evaluate comparator $name', ({ condition, entities, result }) => {
18171905
expect(
18181906
evaluate({

packages/vercel-flags-core/src/evaluate.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ function matchConditions<T>(
156156

157157
const lhsSet = new Set(lhs.filter(isString));
158158

159+
// try to use a set if the lhs is a list of strings - O(1)
159160
if (lhsSet.size === lhs.length) {
160161
return rhs.filter(isString).every((item) => lhsSet.has(item));
161162
}
162163

164+
// otherwise we need to iterate over the values - O(n)
163165
return rhs.every((item) => lhs.includes(item));
164166
}
165167
case Comparator.CONTAINS_ANY_OF: {
@@ -168,8 +170,10 @@ function matchConditions<T>(
168170
const rhsSet = new Set(rhs.filter(isString));
169171
return lhs.some(
170172
rhsSet.size === rhs.length
171-
? (item) => rhsSet.has(item)
172-
: (item) => rhs.includes(item),
173+
? // try to use a set if the rhs is a list of strings - O(1)
174+
(item) => rhsSet.has(item)
175+
: // otherwise we need to iterate over the values - O(n)
176+
(item) => rhs.includes(item),
173177
);
174178
}
175179
case Comparator.CONTAINS_NONE_OF: {
@@ -179,8 +183,10 @@ function matchConditions<T>(
179183
const rhsSet = new Set(rhs.filter(isString));
180184
return lhs.every(
181185
rhsSet.size === rhs.length
182-
? (item) => !rhsSet.has(item)
183-
: (item) => !rhs.includes(item),
186+
? // try to use a set if the rhs is a list of strings - O(1)
187+
(item) => !rhsSet.has(item)
188+
: // otherwise we need to iterate over the values - O(n)
189+
(item) => !rhs.includes(item),
184190
);
185191
}
186192
case Comparator.STARTS_WITH:

packages/vercel-flags-core/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ export namespace Original {
506506
lhs: LHS;
507507
cmp: Comparator;
508508
rhs: RHS;
509+
/** When true, string comparisons are case-insensitive. */
510+
ci?: boolean;
509511
};
510512

511513
export type Rule = {

0 commit comments

Comments
 (0)