Skip to content

Commit c8ba773

Browse files
authored
Merge pull request #13 from schaier-io/dev
feat: added noneFilter
2 parents 7ef01ea + e14c58a commit c8ba773

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/filter/base.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,18 @@ export function anyFilters<X>(
6565
},
6666
};
6767
}
68+
69+
export function noneFilters<X>(
70+
filters: (ErrorFilter<X> | CanHandleErrorFunction<X>)[]
71+
): ErrorFilter<X> {
72+
return {
73+
canHandle: (error: unknown, attempt: number, context: RetryContext<X>) => {
74+
return !filters.some(filter => {
75+
if (typeof filter === 'function') {
76+
return filter(error, attempt, context);
77+
}
78+
return filter.canHandle(error, attempt, context);
79+
});
80+
},
81+
};
82+
}

test/filter/base.spec.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
anyFilters,
44
toErrorFilter,
55
ErrorFilter,
6+
noneFilters,
67
} from '../../src/filter/base';
78

89
describe('filter/base', () => {
@@ -123,6 +124,63 @@ describe('filter/base', () => {
123124
});
124125
});
125126

127+
describe('noneFilters', () => {
128+
it('should handle array of functions', () => {
129+
const filter = noneFilters([() => false, () => false]);
130+
expect(filter.canHandle({}, 0, {})).toBe(true);
131+
});
132+
133+
it('should handle array of ErrorFilters', () => {
134+
const filter = noneFilters([
135+
{ canHandle: () => false },
136+
{ canHandle: () => false },
137+
]);
138+
expect(filter.canHandle({}, 0, {})).toBe(true);
139+
});
140+
141+
it('should handle mixed array of functions and ErrorFilters', () => {
142+
const filter = noneFilters([() => false, { canHandle: () => false }]);
143+
expect(filter.canHandle({}, 0, {})).toBe(true);
144+
});
145+
146+
it('should return false if any filter returns true', () => {
147+
const filter = noneFilters([
148+
() => false,
149+
() => true,
150+
{ canHandle: () => false },
151+
]);
152+
expect(filter.canHandle({}, 0, {})).toBe(false);
153+
});
154+
155+
it('should pass error, attempt and context to filters', () => {
156+
const error = new Error('test');
157+
const attempt = 1;
158+
const context = { data: 'test' };
159+
160+
const functionSpy = jest.fn(() => false);
161+
const filterSpy = jest.fn(() => false);
162+
163+
const filter = noneFilters([functionSpy, { canHandle: filterSpy }]);
164+
165+
filter.canHandle(error, attempt, context);
166+
167+
expect(functionSpy).toHaveBeenCalledWith(error, attempt, context);
168+
expect(filterSpy).toHaveBeenCalledWith(error, attempt, context);
169+
});
170+
171+
it('should short-circuit evaluation when a filter returns true', () => {
172+
const functionSpy = jest.fn(() => true);
173+
const filterSpy = jest.fn(() => false);
174+
175+
const filter = noneFilters([functionSpy, { canHandle: filterSpy }]);
176+
177+
filter.canHandle({}, 0, {});
178+
179+
expect(functionSpy).toHaveBeenCalled();
180+
expect(filterSpy).not.toHaveBeenCalled();
181+
});
182+
});
183+
126184
describe('complex filter combinations', () => {
127185
it('should handle nested filters with allFilters', () => {
128186
const filter = allFilters([
@@ -150,5 +208,13 @@ describe('filter/base', () => {
150208
]);
151209
expect(filter.canHandle({}, 0, {})).toBe(true);
152210
});
211+
212+
it('should handle combinations with noneFilters', () => {
213+
const filter = allFilters([
214+
noneFilters([() => false, { canHandle: () => false }]),
215+
anyFilters([() => true, { canHandle: () => false }]),
216+
]);
217+
expect(filter.canHandle({}, 0, {})).toBe(true);
218+
});
153219
});
154220
});

0 commit comments

Comments
 (0)