Skip to content

Commit aa658d2

Browse files
committed
Improve coverage for cache.ts
1 parent 17cea1b commit aa658d2

File tree

1 file changed

+138
-7
lines changed

1 file changed

+138
-7
lines changed

src/cache_test.ts

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { deepStrictEqual, notStrictEqual, strictEqual, throws } from 'node:assert';
1+
import { deepStrictEqual, deepEqual, fail, notStrictEqual, strictEqual, throws } from 'node:assert';
22
import mock from 'ts-mockito';
33

44
import { V1Namespace, V1NamespaceList, V1ObjectMeta, V1Pod, V1PodList, V1ListMeta } from './api.js';
@@ -244,11 +244,20 @@ describe('ListWatchCache', () => {
244244
} as V1ObjectMeta,
245245
} as V1Namespace);
246246

247-
watchHandler('DELETED', {
248-
metadata: {
249-
name: 'name2',
250-
} as V1ObjectMeta,
251-
} as V1Namespace);
247+
watchHandler(
248+
'DELETED',
249+
{
250+
metadata: {
251+
name: 'name2',
252+
resourceVersion: 'blah',
253+
} as V1ObjectMeta,
254+
} as V1Namespace,
255+
{
256+
metadata: {
257+
resourceVersion: '54321',
258+
},
259+
},
260+
);
252261

253262
const [addResult, updateResult, deleteResult] = await Promise.all([
254263
addPromise,
@@ -257,7 +266,19 @@ describe('ListWatchCache', () => {
257266
]);
258267
deepStrictEqual(addResult.metadata, { name: 'name3' });
259268
deepStrictEqual(updateResult.metadata, { name: 'name3', resourceVersion: 'baz' });
260-
deepStrictEqual(deleteResult.metadata, { name: 'name2' });
269+
deepStrictEqual(deleteResult.metadata, { name: 'name2', resourceVersion: 'blah' });
270+
strictEqual(informer.latestResourceVersion(), '54321');
271+
272+
watchHandler(
273+
'BOOKMARK',
274+
{},
275+
{
276+
metadata: {
277+
resourceVersion: '5454',
278+
},
279+
},
280+
);
281+
strictEqual(informer.latestResourceVersion(), '5454');
261282
});
262283

263284
it('should handle change events correctly', async () => {
@@ -789,6 +810,116 @@ describe('ListWatchCache', () => {
789810
strictEqual(addedList2.length, 1);
790811
});
791812

813+
it('should unregister three verbs on "change"', async () => {
814+
const fakeWatch = mock.mock(Watch);
815+
const list: V1Namespace[] = [];
816+
const listObj = {
817+
metadata: {
818+
resourceVersion: '12345',
819+
} as V1ListMeta,
820+
items: list,
821+
} as V1NamespaceList;
822+
const listFn: ListPromise<V1Namespace> = function (): Promise<V1NamespaceList> {
823+
return new Promise<V1NamespaceList>((resolve) => {
824+
resolve(listObj);
825+
});
826+
};
827+
const watchCalled = new Promise((resolve) => {
828+
mock.when(
829+
fakeWatch.watch(mock.anything(), mock.anything(), mock.anything(), mock.anything()),
830+
).thenCall(resolve);
831+
});
832+
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn);
833+
834+
const changeList1: V1Namespace[] = [];
835+
const changeToList1Fn = function (obj?: V1Namespace) {
836+
changeList1.push(obj!);
837+
};
838+
const changeList2: V1Namespace[] = [];
839+
const changeToList2Fn = function (obj?: V1Namespace) {
840+
changeList2.push(obj!);
841+
};
842+
843+
informer.start();
844+
845+
await watchCalled;
846+
const [, , watchHandler] = mock.capture(fakeWatch.watch).last();
847+
848+
informer.on('change', changeToList1Fn);
849+
informer.on('change', changeToList2Fn);
850+
851+
['ADDED', 'DELETED', 'MODIFIED'].forEach((verb) => {
852+
watchHandler(verb, {
853+
metadata: {
854+
name: 'name1',
855+
} as V1ObjectMeta,
856+
} as V1Namespace);
857+
});
858+
strictEqual(changeList1.length, 3);
859+
strictEqual(changeList2.length, 3);
860+
861+
informer.off('change', changeToList2Fn);
862+
863+
['ADDED', 'DELETED', 'MODIFIED'].forEach((verb) => {
864+
watchHandler(verb, {
865+
metadata: {
866+
name: 'name2',
867+
} as V1ObjectMeta,
868+
} as V1Namespace);
869+
});
870+
871+
strictEqual(changeList1.length, 6);
872+
strictEqual(changeList2.length, 3);
873+
});
874+
875+
it('should throw on unknown verbs', async () => {
876+
const fakeWatch = mock.mock(Watch);
877+
const list: V1Namespace[] = [];
878+
const listObj = {
879+
metadata: {
880+
resourceVersion: '12345',
881+
} as V1ListMeta,
882+
items: list,
883+
} as V1NamespaceList;
884+
const listFn: ListPromise<V1Namespace> = function (): Promise<V1NamespaceList> {
885+
return new Promise<V1NamespaceList>((resolve) => {
886+
resolve(listObj);
887+
});
888+
};
889+
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn);
890+
try {
891+
informer.on('random' as any /* trick Typescript to allow this */, (obj) => {});
892+
fail('Unexpected lack of exception');
893+
} catch (err) {
894+
deepEqual(err, Error('Unknown verb: random'));
895+
}
896+
try {
897+
informer.off('random' as any /* trick Typescript to allow this */, (obj) => {});
898+
fail('Unexpected lack of exception');
899+
} catch (err) {
900+
deepEqual(err, Error('Unknown verb: random'));
901+
}
902+
});
903+
904+
it('should handle off with callbacks that are not registered', async () => {
905+
const fakeWatch = mock.mock(Watch);
906+
const list: V1Namespace[] = [];
907+
const listObj = {
908+
metadata: {
909+
resourceVersion: '12345',
910+
} as V1ListMeta,
911+
items: list,
912+
} as V1NamespaceList;
913+
const listFn: ListPromise<V1Namespace> = function (): Promise<V1NamespaceList> {
914+
return new Promise<V1NamespaceList>((resolve) => {
915+
resolve(listObj);
916+
});
917+
};
918+
const informer = new ListWatch('/some/path', mock.instance(fakeWatch), listFn);
919+
informer.off('add', (obj) => {});
920+
// No assertion because we're just looking to see if it throws.
921+
});
922+
792923
it('mutating handlers in a callback should not affect those which remain', async () => {
793924
const fakeWatch = mock.mock(Watch);
794925
const list: V1Namespace[] = [];

0 commit comments

Comments
 (0)