import { updateCallbacks, storeCallback } from '../../lib/api/callbacks';
import type { IconStorageWithAPI } from '../../lib/api/types';
import { sortIcons } from '../../lib/icon/sort';
import { getStorage, addIconSet } from '../../lib/storage/storage';
describe('Testing API callbacks', () => {
let prefixCounter = 0;
function nextPrefix(): string {
prefixCounter++;
return (
'api-cb-test-' +
(prefixCounter < 10 ? '0' : '') +
prefixCounter.toString()
);
}
it('Simple callback', (done) => {
const provider = 'iconify';
const prefix = nextPrefix();
let counter = 0;
const storage = getStorage(provider, prefix) as IconStorageWithAPI;
const abort = storeCallback(
(loaded, missing, pending, unsubscribe) => {
expect(unsubscribe).toBe(abort);
counter++;
switch (counter) {
case 1:
// First run - icon1 should be loaded, icon3 should be missing
expect(loaded).toEqual([
{
provider,
prefix,
name: 'icon1',
},
]);
expect(missing).toEqual([
{
provider,
prefix,
name: 'icon3',
},
]);
expect(pending).toEqual([
{
provider,
prefix,
name: 'icon2',
},
]);
expect(storage.loaderCallbacks?.length).toBe(1);
// Add icon2 and trigger update
addIconSet(storage, {
prefix: prefix,
icons: {
icon2: {
body: '',
},
},
});
updateCallbacks(storage);
return;
case 2:
// Second run - icon2 should be added, completing callback
expect(loaded).toEqual([
{
provider,
prefix,
name: 'icon1',
},
{
provider,
prefix,
name: 'icon2',
},
]);
expect(missing).toEqual([
{
provider,
prefix,
name: 'icon3',
},
]);
expect(pending).toEqual([]);
expect(storage.loaderCallbacks?.length).toBe(0);
done();
}
},
sortIcons([
{
provider,
prefix,
name: 'icon1',
},
{
provider,
prefix,
name: 'icon2',
},
{
provider,
prefix,
name: 'icon3',
},
]),
[storage]
);
// Test callbacks
expect(storage.loaderCallbacks?.length).toBe(1);
// Test update - should do nothing
updateCallbacks(storage);
// Wait for tick because updateCallbacks will use one
setTimeout(() => {
// Callback should not have been called yet
expect(counter).toBe(0);
// Add few icons and run updateCallbacks
addIconSet(storage, {
prefix: prefix,
icons: {
icon1: {
body: '',
},
},
not_found: ['icon3'],
});
updateCallbacks(storage);
});
});
it('Callback that should not be stored', () => {
const provider = '';
const prefix = nextPrefix();
const storage = getStorage(provider, prefix) as IconStorageWithAPI;
addIconSet(storage, {
prefix,
icons: {
icon1: {
body: '',
},
icon2: {
body: '',
},
},
not_found: ['icon3'],
});
storeCallback(
() => {
throw new Error('This code should not be executed!');
},
sortIcons([
{
provider,
prefix,
name: 'icon1',
},
{
provider,
prefix,
name: 'icon2',
},
{
provider,
prefix,
name: 'icon3',
},
]),
[storage]
);
// callbacks should not have been initialised
expect(storage.loaderCallbacks).toBeUndefined();
});
it('Cancel callback', (done) => {
const provider = 'foo';
const prefix = nextPrefix();
let counter = 0;
const storage = getStorage(provider, prefix) as IconStorageWithAPI;
const abort = storeCallback(
(loaded, missing, pending, unsubscribe) => {
expect(unsubscribe).toBe(abort);
counter++;
expect(counter).toBe(1);
// First run - icon1 should be loaded, icon3 should be missing
expect(loaded).toEqual([
{
provider,
prefix,
name: 'icon1',
},
]);
expect(missing).toEqual([
{
provider,
prefix,
name: 'icon3',
},
]);
expect(pending).toEqual([
{
provider,
prefix,
name: 'icon2',
},
]);
expect(storage.loaderCallbacks?.length).toBe(1);
// Add icon2 and trigger update
addIconSet(storage, {
prefix: prefix,
icons: {
icon2: {
body: '',
},
},
});
updateCallbacks(storage);
// Unsubscribe and set timer to call done()
unsubscribe();
expect(storage.loaderCallbacks?.length).toBe(0);
setTimeout(done);
},
sortIcons([
{
provider,
prefix,
name: 'icon1',
},
{
provider,
prefix,
name: 'icon2',
},
{
provider,
prefix,
name: 'icon3',
},
]),
[storage]
);
// Test callbacks
expect(storage.loaderCallbacks?.length).toBe(1);
// Test update - should do nothing
updateCallbacks(storage);
// Wait for tick because updateCallbacks will use one
setTimeout(() => {
// Callback should not have been called yet
expect(counter).toBe(0);
// Add few icons and run updateCallbacks
addIconSet(storage, {
prefix: prefix,
icons: {
icon1: {
body: '',
},
},
not_found: ['icon3'],
});
updateCallbacks(storage);
});
});
it('Multiple prefixes', (done) => {
const provider = '';
const prefix1 = nextPrefix();
const prefix2 = nextPrefix();
let counter = 0;
const storage1 = getStorage(provider, prefix1) as IconStorageWithAPI;
const storage2 = getStorage(provider, prefix2) as IconStorageWithAPI;
const abort = storeCallback(
(loaded, missing, pending, unsubscribe) => {
expect(unsubscribe).toBe(abort);
counter++;
switch (counter) {
case 1:
// First run - icon1 should be loaded, icon3 should be missing
expect(loaded).toEqual([
{
provider,
prefix: prefix1,
name: 'icon1',
},
]);
expect(missing).toEqual([
{
provider,
prefix: prefix1,
name: 'icon3',
},
]);
expect(pending).toEqual([
{
provider,
prefix: prefix2,
name: 'icon2',
},
]);
expect(storage1.loaderCallbacks?.length).toBe(0);
expect(storage2.loaderCallbacks?.length).toBe(1);
// Add icon2 and trigger update
addIconSet(storage2, {
prefix: prefix2,
icons: {
icon2: {
body: '',
},
},
});
updateCallbacks(storage2);
break;
case 2:
// Second run - icon2 should be loaded
expect(storage1.loaderCallbacks?.length).toBe(0);
expect(storage2.loaderCallbacks?.length).toBe(0);
done();
break;
default:
done(`Callback was called ${counter} times.`);
}
},
sortIcons([
{
provider,
prefix: prefix1,
name: 'icon1',
},
{
provider,
prefix: prefix2,
name: 'icon2',
},
{
provider,
prefix: prefix1,
name: 'icon3',
},
]),
[storage1, storage2]
);
// Test callbacks
expect(storage1.loaderCallbacks?.length).toBe(1);
expect(storage2.loaderCallbacks?.length).toBe(1);
// Test update - should do nothing
updateCallbacks(storage1);
// Wait for tick because updateCallbacks will use one
setTimeout(() => {
// Callback should not have been called yet
expect(counter).toBe(0);
// Add few icons and run updateCallbacks
addIconSet(storage1, {
prefix: prefix1,
icons: {
icon1: {
body: '',
},
},
not_found: ['icon3'],
});
updateCallbacks(storage1);
});
});
it('Multiple providers', (done) => {
const provider1 = nextPrefix();
const provider2 = nextPrefix();
const prefix1 = nextPrefix();
const prefix2 = nextPrefix();
let counter = 0;
const storage1 = getStorage(provider1, prefix1) as IconStorageWithAPI;
const storage2 = getStorage(provider2, prefix2) as IconStorageWithAPI;
const abort = storeCallback(
(loaded, missing, pending, unsubscribe) => {
expect(unsubscribe).toBe(abort);
counter++;
switch (counter) {
case 1:
// First run - icon1 should be loaded, icon3 should be missing
expect(loaded).toEqual([
{
provider: provider1,
prefix: prefix1,
name: 'icon1',
},
]);
expect(missing).toEqual([
{
provider: provider1,
prefix: prefix1,
name: 'icon3',
},
]);
expect(pending).toEqual([
{
provider: provider2,
prefix: prefix2,
name: 'icon2',
},
]);
expect(storage1.loaderCallbacks?.length).toBe(0);
expect(storage2.loaderCallbacks?.length).toBe(1);
// Add icon2 and trigger update
addIconSet(storage2, {
prefix: prefix2,
icons: {
icon2: {
body: '',
},
},
});
updateCallbacks(storage2);
break;
case 2:
// Second run - icon2 should be loaded
expect(storage1.loaderCallbacks?.length).toBe(0);
expect(storage2.loaderCallbacks?.length).toBe(0);
done();
break;
default:
done(`Callback was called ${counter} times.`);
}
},
sortIcons([
{
provider: provider1,
prefix: prefix1,
name: 'icon1',
},
{
provider: provider2,
prefix: prefix2,
name: 'icon2',
},
{
provider: provider1,
prefix: prefix1,
name: 'icon3',
},
]),
[storage1, storage2]
);
// Test callbacks
expect(storage1.loaderCallbacks?.length).toBe(1);
expect(storage2.loaderCallbacks?.length).toBe(1);
// Test update - should do nothing
updateCallbacks(storage1);
// Wait for tick because updateCallbacks will use one
setTimeout(() => {
// Callback should not have been called yet
expect(counter).toBe(0);
// Add few icons and run updateCallbacks
addIconSet(storage1, {
prefix: prefix1,
icons: {
icon1: {
body: '',
},
},
not_found: ['icon3'],
});
updateCallbacks(storage1);
});
});
});