mirror of
https://github.com/iconify/iconify.git
synced 2024-12-13 14:13:06 +00:00
Merge branch 'dev/redundancy'
This commit is contained in:
commit
ded43ed8fc
@ -15,6 +15,6 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
'no-mixed-spaces-and-tabs': ['off'],
|
'no-mixed-spaces-and-tabs': ['off'],
|
||||||
'no-unused-vars': ['off'],
|
'no-unused-vars': ['off'],
|
||||||
'@typescript-eslint/no-unused-vars-experimental': ['error'],
|
// '@typescript-eslint/no-unused-vars-experimental': ['error'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
3671
packages/api-redundancy/package-lock.json
generated
3671
packages/api-redundancy/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,16 +30,16 @@
|
|||||||
"directory": "packages/api-redundancy"
|
"directory": "packages/api-redundancy"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.0.1",
|
"@types/jest": "^27.4.0",
|
||||||
"@types/node": "^16.9.4",
|
"@types/node": "^17.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.31.1",
|
"@typescript-eslint/eslint-plugin": "^5.10.1",
|
||||||
"@typescript-eslint/parser": "^4.31.1",
|
"@typescript-eslint/parser": "^5.10.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^8.7.0",
|
||||||
"eslint-plugin-jasmine": "^4.1.2",
|
"eslint-plugin-jasmine": "^4.1.3",
|
||||||
"jasmine": "^3.9.0",
|
"jasmine": "^4.0.2",
|
||||||
"jest": "^27.2.0",
|
"jest": "^27.4.7",
|
||||||
"ts-jest": "^27.0.5",
|
"ts-jest": "^27.1.3",
|
||||||
"tsup": "^5.1.0"
|
"tsup": "^5.11.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ describe('Redundancy class', () => {
|
|||||||
|
|
||||||
const query = redundancy.query(
|
const query = redundancy.query(
|
||||||
'/foo',
|
'/foo',
|
||||||
(resource, payload, status) => {
|
(resource, payload, callback) => {
|
||||||
counter++;
|
counter++;
|
||||||
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ describe('Redundancy class', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do something with "data", simulate instant callback
|
// Do something with "data", simulate instant callback
|
||||||
status.done(responses[uri]);
|
callback('success', responses[uri]);
|
||||||
|
|
||||||
// Complete test
|
// Complete test
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -78,7 +78,9 @@ describe('Redundancy class', () => {
|
|||||||
};
|
};
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const query = redundancy.query('/foo', (resource, payload, status) => {
|
const query = redundancy.query(
|
||||||
|
'/foo',
|
||||||
|
(resource, payload, callback) => {
|
||||||
counter++;
|
counter++;
|
||||||
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
||||||
|
|
||||||
@ -91,7 +93,7 @@ describe('Redundancy class', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do something with "data", simulate instant callback
|
// Do something with "data", simulate instant callback
|
||||||
status.done(responses[uri]);
|
callback('success', responses[uri]);
|
||||||
|
|
||||||
// Complete test
|
// Complete test
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -100,7 +102,8 @@ describe('Redundancy class', () => {
|
|||||||
expect(redundancy.getIndex()).toEqual(1);
|
expect(redundancy.getIndex()).toEqual(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Test find()
|
// Test find()
|
||||||
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
||||||
|
@ -1,24 +1,3 @@
|
|||||||
/**
|
|
||||||
* Callback for "timeout" configuration property.
|
|
||||||
* Returns number of milliseconds to wait before failing query, while there are pending resources.
|
|
||||||
*/
|
|
||||||
export interface TimeoutCallback {
|
|
||||||
(
|
|
||||||
startTime: number // Start time
|
|
||||||
): number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for "rotate" configuration property.
|
|
||||||
* Returns number of milliseconds to wait before trying next resource.
|
|
||||||
*/
|
|
||||||
export interface RotationTimeoutCallback {
|
|
||||||
(
|
|
||||||
queriesSent: number, // Number of queries sent, starts with 1 for timeout after first resource
|
|
||||||
startTime: number // Query start time
|
|
||||||
): number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource to rotate (usually hostname or partial URL)
|
* Resource to rotate (usually hostname or partial URL)
|
||||||
*/
|
*/
|
||||||
@ -30,8 +9,8 @@ export type RedundancyResource = string;
|
|||||||
export interface RedundancyConfig {
|
export interface RedundancyConfig {
|
||||||
resources: RedundancyResource[]; // Resources to rotate
|
resources: RedundancyResource[]; // Resources to rotate
|
||||||
index: number; // Start index
|
index: number; // Start index
|
||||||
timeout: number | TimeoutCallback; // Timeout for error (full timeout = timeout + resources.length * rotate)
|
timeout: number; // Timeout for error (full timeout = timeout + resources.length * rotate)
|
||||||
rotate: number | RotationTimeoutCallback; // Timeout for one query
|
rotate: number; // Timeout for one query
|
||||||
random: boolean; // True if order should be randomised
|
random: boolean; // True if order should be randomised
|
||||||
dataAfterTimeout: boolean; // True if data can be sent after timeout
|
dataAfterTimeout: boolean; // True if data can be sent after timeout
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ import { sendQuery } from './query';
|
|||||||
export { GetQueryStatus, QueryModuleCallback, QueryDoneCallback };
|
export { GetQueryStatus, QueryModuleCallback, QueryDoneCallback };
|
||||||
export type {
|
export type {
|
||||||
QueryAbortCallback,
|
QueryAbortCallback,
|
||||||
QueryUpdateIndexCallback,
|
|
||||||
QueryStatus,
|
QueryStatus,
|
||||||
PendingQueryItem,
|
QueryModuleResponseType,
|
||||||
|
QueryModuleResponse,
|
||||||
} from './query';
|
} from './query';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,10 +117,6 @@ export function initRedundancy(cfg: Partial<RedundancyConfig>): Redundancy {
|
|||||||
if (doneCallback) {
|
if (doneCallback) {
|
||||||
doneCallback(data, error);
|
doneCallback(data, error);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
(newIndex) => {
|
|
||||||
// Update start index
|
|
||||||
config.index = newIndex;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
queries.push(query);
|
queries.push(query);
|
||||||
|
@ -11,12 +11,20 @@ type QueryItemStatus = 'pending' | 'completed' | 'aborted' | 'failed';
|
|||||||
*/
|
*/
|
||||||
type QueryPayload = unknown;
|
type QueryPayload = unknown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response from query module
|
||||||
|
*/
|
||||||
|
export type QueryModuleResponseData = unknown;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback
|
* Callback
|
||||||
*
|
*
|
||||||
* If error is present, something went wrong and data is undefined. If error is undefined, data is set.
|
* If error is present, something went wrong and data is undefined. If error is undefined, data is set.
|
||||||
*/
|
*/
|
||||||
export type QueryDoneCallback = (data?: unknown, error?: unknown) => void;
|
export type QueryDoneCallback = (
|
||||||
|
data?: QueryModuleResponseData,
|
||||||
|
error?: QueryModuleResponseData
|
||||||
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for "abort" pending item.
|
* Callback for "abort" pending item.
|
||||||
@ -24,9 +32,13 @@ export type QueryDoneCallback = (data?: unknown, error?: unknown) => void;
|
|||||||
export type QueryAbortCallback = () => void;
|
export type QueryAbortCallback = () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to call to update last successful resource index. Used by Resundancy class to automatically update config.
|
* Response from query module
|
||||||
*/
|
*/
|
||||||
export type QueryUpdateIndexCallback = (index: number) => void;
|
export type QueryModuleResponseType = 'success' | 'next' | 'abort';
|
||||||
|
export type QueryModuleResponse = (
|
||||||
|
status: QueryModuleResponseType,
|
||||||
|
data: QueryModuleResponseData
|
||||||
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status for query
|
* Status for query
|
||||||
@ -52,12 +64,10 @@ export type GetQueryStatus = () => QueryStatus;
|
|||||||
/**
|
/**
|
||||||
* Item in pending items list
|
* Item in pending items list
|
||||||
*/
|
*/
|
||||||
export interface PendingQueryItem {
|
interface PendingQueryItem {
|
||||||
readonly getQueryStatus: GetQueryStatus;
|
|
||||||
status: QueryItemStatus; // Current query status
|
status: QueryItemStatus; // Current query status
|
||||||
readonly resource: RedundancyResource; // Resource
|
readonly resource: RedundancyResource; // Resource
|
||||||
readonly done: QueryDoneCallback; // Function to call with data
|
readonly callback: QueryModuleResponse; // Function to call with data
|
||||||
abort?: QueryAbortCallback; // Function to call to abort query, set by query handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +76,7 @@ export interface PendingQueryItem {
|
|||||||
export type QueryModuleCallback = (
|
export type QueryModuleCallback = (
|
||||||
resource: RedundancyResource,
|
resource: RedundancyResource,
|
||||||
payload: QueryPayload,
|
payload: QueryPayload,
|
||||||
queryItem: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,10 +84,9 @@ export type QueryModuleCallback = (
|
|||||||
*/
|
*/
|
||||||
export function sendQuery(
|
export function sendQuery(
|
||||||
config: RedundancyConfig,
|
config: RedundancyConfig,
|
||||||
payload: unknown,
|
payload: QueryPayload,
|
||||||
query: QueryModuleCallback,
|
query: QueryModuleCallback,
|
||||||
done?: QueryDoneCallback,
|
done?: QueryDoneCallback
|
||||||
success?: QueryUpdateIndexCallback
|
|
||||||
): GetQueryStatus {
|
): GetQueryStatus {
|
||||||
// Get number of resources
|
// Get number of resources
|
||||||
const resourcesCount = config.resources.length;
|
const resourcesCount = config.resources.length;
|
||||||
@ -110,7 +119,7 @@ export function sendQuery(
|
|||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let status: QueryItemStatus = 'pending';
|
let status: QueryItemStatus = 'pending';
|
||||||
let queriesSent = 0;
|
let queriesSent = 0;
|
||||||
let lastError: unknown = void 0;
|
let lastError: QueryModuleResponseData | undefined;
|
||||||
|
|
||||||
// Timer
|
// Timer
|
||||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||||
@ -148,9 +157,6 @@ export function sendQuery(
|
|||||||
|
|
||||||
// Abort all queued items
|
// Abort all queued items
|
||||||
queue.forEach((item) => {
|
queue.forEach((item) => {
|
||||||
if (item.abort) {
|
|
||||||
item.abort();
|
|
||||||
}
|
|
||||||
if (item.status === 'pending') {
|
if (item.status === 'pending') {
|
||||||
item.status = 'aborted';
|
item.status = 'aborted';
|
||||||
}
|
}
|
||||||
@ -205,15 +211,12 @@ export function sendQuery(
|
|||||||
* Clear queue
|
* Clear queue
|
||||||
*/
|
*/
|
||||||
function clearQueue(): void {
|
function clearQueue(): void {
|
||||||
queue = queue.filter((item) => {
|
queue.forEach((item) => {
|
||||||
if (item.status === 'pending') {
|
if (item.status === 'pending') {
|
||||||
item.status = 'aborted';
|
item.status = 'aborted';
|
||||||
}
|
}
|
||||||
if (item.abort) {
|
|
||||||
item.abort();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
queue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,10 +224,10 @@ export function sendQuery(
|
|||||||
*/
|
*/
|
||||||
function moduleResponse(
|
function moduleResponse(
|
||||||
item: PendingQueryItem,
|
item: PendingQueryItem,
|
||||||
data?: unknown,
|
response: QueryModuleResponseType,
|
||||||
error?: unknown
|
data: QueryModuleResponseData
|
||||||
): void {
|
): void {
|
||||||
const isError = data === void 0;
|
const isError = response !== 'success';
|
||||||
|
|
||||||
// Remove item from queue
|
// Remove item from queue
|
||||||
queue = queue.filter((queued) => queued !== item);
|
queue = queue.filter((queued) => queued !== item);
|
||||||
@ -248,11 +251,16 @@ export function sendQuery(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abort
|
||||||
|
if (response === 'abort') {
|
||||||
|
lastError = data;
|
||||||
|
failQuery();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
if (isError) {
|
if (isError) {
|
||||||
if (error !== void 0) {
|
lastError = data;
|
||||||
lastError = error;
|
|
||||||
}
|
|
||||||
if (!queue.length) {
|
if (!queue.length) {
|
||||||
if (!resources.length) {
|
if (!resources.length) {
|
||||||
// Nothing else queued, nothing can be queued
|
// Nothing else queued, nothing can be queued
|
||||||
@ -270,11 +278,11 @@ export function sendQuery(
|
|||||||
resetTimer();
|
resetTimer();
|
||||||
clearQueue();
|
clearQueue();
|
||||||
|
|
||||||
// Update index in Redundancy
|
// Update index in configuration
|
||||||
if (success && !config.random) {
|
if (!config.random) {
|
||||||
const index = config.resources.indexOf(item.resource);
|
const index = config.resources.indexOf(item.resource);
|
||||||
if (index !== -1 && index !== config.index) {
|
if (index !== -1 && index !== config.index) {
|
||||||
success(index);
|
config.index = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,11 +310,6 @@ export function sendQuery(
|
|||||||
if (resource === void 0) {
|
if (resource === void 0) {
|
||||||
// Nothing to execute: wait for final timeout before failing
|
// Nothing to execute: wait for final timeout before failing
|
||||||
if (queue.length) {
|
if (queue.length) {
|
||||||
const timeout: number =
|
|
||||||
typeof config.timeout === 'function'
|
|
||||||
? config.timeout(startTime)
|
|
||||||
: config.timeout;
|
|
||||||
if (timeout) {
|
|
||||||
// Last timeout before failing to allow late response
|
// Last timeout before failing to allow late response
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
resetTimer();
|
resetTimer();
|
||||||
@ -315,10 +318,9 @@ export function sendQuery(
|
|||||||
clearQueue();
|
clearQueue();
|
||||||
failQuery();
|
failQuery();
|
||||||
}
|
}
|
||||||
}, timeout);
|
}, config.timeout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fail
|
// Fail
|
||||||
failQuery();
|
failQuery();
|
||||||
@ -327,11 +329,10 @@ export function sendQuery(
|
|||||||
|
|
||||||
// Create new item
|
// Create new item
|
||||||
const item: PendingQueryItem = {
|
const item: PendingQueryItem = {
|
||||||
getQueryStatus,
|
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
resource,
|
resource,
|
||||||
done: (data?: unknown, error?: unknown) => {
|
callback: (status, data) => {
|
||||||
moduleResponse(item, data, error);
|
moduleResponse(item, status, data);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -341,17 +342,11 @@ export function sendQuery(
|
|||||||
// Bump next index
|
// Bump next index
|
||||||
queriesSent++;
|
queriesSent++;
|
||||||
|
|
||||||
// Get timeout for next item
|
|
||||||
const timeout: number =
|
|
||||||
typeof config.rotate === 'function'
|
|
||||||
? config.rotate(queriesSent, startTime)
|
|
||||||
: config.rotate;
|
|
||||||
|
|
||||||
// Create timer
|
// Create timer
|
||||||
timer = setTimeout(execNext, timeout);
|
timer = setTimeout(execNext, config.rotate);
|
||||||
|
|
||||||
// Execute it
|
// Execute it
|
||||||
query(resource, payload, item);
|
query(resource, payload, item.callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute first query on next tick
|
// Execute first query on next tick
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { RedundancyConfig } from '../src/config';
|
import type { RedundancyConfig } from '../src/config';
|
||||||
import type { PendingQueryItem } from '../src/query';
|
import type { QueryModuleResponse } from '../src/query';
|
||||||
import { sendQuery } from '../src/query';
|
import { sendQuery } from '../src/query';
|
||||||
|
|
||||||
describe('Advanced queries with multiple resources', () => {
|
describe('Advanced queries with multiple resources', () => {
|
||||||
@ -20,14 +20,13 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let itemAborted = false;
|
let secondCallback: QueryModuleResponse;
|
||||||
let secondItem: PendingQueryItem;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -36,7 +35,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -51,13 +49,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Add abort
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done(
|
|
||||||
'Abort should have not been called for first item'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fail in 20ms
|
// Fail in 20ms
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Status should not have changed
|
// Status should not have changed
|
||||||
@ -66,7 +57,7 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Fail
|
// Fail
|
||||||
queryItem.done(void 0, true);
|
callback('next', true);
|
||||||
}, 20);
|
}, 20);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -75,15 +66,8 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(2);
|
expect(status.queriesSent).toEqual(2);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Add abort
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done(
|
|
||||||
'Abort should have not been called for second item'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Save item
|
// Save item
|
||||||
secondItem = queryItem;
|
secondCallback = callback;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
@ -91,16 +75,8 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(3);
|
expect(status.queriesSent).toEqual(3);
|
||||||
expect(status.queriesPending).toEqual(2);
|
expect(status.queriesPending).toEqual(2);
|
||||||
|
|
||||||
// Add abort
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
// This item should be aborted, but only once
|
|
||||||
expect(itemAborted).toEqual(false);
|
|
||||||
expect(sentQuery).toEqual(3);
|
|
||||||
itemAborted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Complete second item
|
// Complete second item
|
||||||
secondItem.done(result);
|
secondCallback('success', result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -111,9 +87,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
// Make sure queries were sent
|
// Make sure queries were sent
|
||||||
expect(sentQuery).toEqual(3);
|
expect(sentQuery).toEqual(3);
|
||||||
|
|
||||||
// Third query should have been aborted
|
|
||||||
expect(itemAborted).toEqual(true);
|
|
||||||
|
|
||||||
// Validate data
|
// Validate data
|
||||||
expect(data).toEqual(result);
|
expect(data).toEqual(result);
|
||||||
expect(error).toBeUndefined();
|
expect(error).toBeUndefined();
|
||||||
@ -159,14 +132,13 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let itemAborted = false;
|
let firstCallback: QueryModuleResponse;
|
||||||
let firstItem: PendingQueryItem;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -175,7 +147,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -190,15 +161,8 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Add abort
|
// Store callback
|
||||||
queryItem.abort = (): void => {
|
firstCallback = callback;
|
||||||
done(
|
|
||||||
'Abort should have not been called for first item'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Store item
|
|
||||||
firstItem = queryItem;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -206,12 +170,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(2);
|
expect(status.queriesSent).toEqual(2);
|
||||||
expect(status.queriesPending).toEqual(2);
|
expect(status.queriesPending).toEqual(2);
|
||||||
|
|
||||||
// Add abort
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
expect(itemAborted).toEqual(false);
|
|
||||||
itemAborted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Complete first item in 20ms (70ms from start), then second item
|
// Complete first item in 20ms (70ms from start), then second item
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Check status
|
// Check status
|
||||||
@ -220,14 +178,12 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(2);
|
expect(status.queriesSent).toEqual(2);
|
||||||
expect(status.queriesPending).toEqual(2);
|
expect(status.queriesPending).toEqual(2);
|
||||||
|
|
||||||
firstItem.done(result1);
|
firstCallback('success', result1);
|
||||||
|
|
||||||
// Complete second item in 30 ms
|
// Complete second item in 30 ms
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(queryItem.status).toEqual('aborted');
|
|
||||||
|
|
||||||
// Should not change anything because query is already complete
|
// Should not change anything because query is already complete
|
||||||
queryItem.done(result2);
|
callback('success', result2);
|
||||||
|
|
||||||
// Finish test
|
// Finish test
|
||||||
done();
|
done();
|
||||||
@ -243,9 +199,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
// Make sure queries were sent
|
// Make sure queries were sent
|
||||||
expect(sentQuery).toEqual(2);
|
expect(sentQuery).toEqual(2);
|
||||||
|
|
||||||
// Second query should have been aborted
|
|
||||||
expect(itemAborted).toEqual(true);
|
|
||||||
|
|
||||||
// Validate data
|
// Validate data
|
||||||
expect(data).toEqual(result1);
|
expect(data).toEqual(result1);
|
||||||
expect(error).toBeUndefined();
|
expect(error).toBeUndefined();
|
||||||
@ -290,14 +243,14 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let firstItem: PendingQueryItem;
|
let firstCallback: QueryModuleResponse;
|
||||||
let completeCount = 0;
|
let completeCount = 0;
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -306,7 +259,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -321,8 +273,8 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Store item
|
// Store callback
|
||||||
firstItem = queryItem;
|
firstCallback = callback;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -360,7 +312,7 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(diff > 130 && diff < 170).toEqual(true);
|
expect(diff > 130 && diff < 170).toEqual(true);
|
||||||
|
|
||||||
// Send data from first query, which should be ignored because dataAfterTimeout is false
|
// Send data from first query, which should be ignored because dataAfterTimeout is false
|
||||||
firstItem.done(result);
|
firstCallback('success', result);
|
||||||
|
|
||||||
// Complete test
|
// Complete test
|
||||||
done();
|
done();
|
||||||
@ -399,14 +351,14 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let firstItem: PendingQueryItem;
|
let firstCallback: QueryModuleResponse;
|
||||||
let completeCount = 0;
|
let completeCount = 0;
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -415,7 +367,6 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -430,8 +381,8 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Store item
|
// Store callback
|
||||||
firstItem = queryItem;
|
firstCallback = callback;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -469,7 +420,7 @@ describe('Advanced queries with multiple resources', () => {
|
|||||||
expect(diff > 130 && diff < 170).toEqual(true);
|
expect(diff > 130 && diff < 170).toEqual(true);
|
||||||
|
|
||||||
// Send data from first query
|
// Send data from first query
|
||||||
firstItem.done(result);
|
firstCallback('success', result);
|
||||||
})();
|
})();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ describe('Basic queries', () => {
|
|||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(resource).toEqual(resources[0]);
|
expect(resource).toEqual(resources[0]);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
@ -84,20 +84,14 @@ describe('Basic queries', () => {
|
|||||||
sentQuery = true;
|
sentQuery = true;
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Add abort function
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done('Abort should have not been called');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
queryItem.done(result);
|
callback('success', result);
|
||||||
},
|
},
|
||||||
(data, error) => {
|
(data, error) => {
|
||||||
// Make sure query was sent
|
// Make sure query was sent
|
||||||
@ -152,7 +146,7 @@ describe('Basic queries', () => {
|
|||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(resource).toEqual(resources[0]);
|
expect(resource).toEqual(resources[0]);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
@ -161,13 +155,8 @@ describe('Basic queries', () => {
|
|||||||
expect(sentQuery).toEqual(false);
|
expect(sentQuery).toEqual(false);
|
||||||
sentQuery = true;
|
sentQuery = true;
|
||||||
|
|
||||||
// Add abort function
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done('Abort should have not been called');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fail
|
// Fail
|
||||||
queryItem.done(void 0, result);
|
callback('next', result);
|
||||||
},
|
},
|
||||||
(data, error) => {
|
(data, error) => {
|
||||||
// Make sure query was sent
|
// Make sure query was sent
|
||||||
@ -216,13 +205,12 @@ describe('Basic queries', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = false;
|
let sentQuery = false;
|
||||||
let itemAborted = false;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(resource).toEqual(resources[0]);
|
expect(resource).toEqual(resources[0]);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
@ -231,12 +219,6 @@ describe('Basic queries', () => {
|
|||||||
expect(sentQuery).toEqual(false);
|
expect(sentQuery).toEqual(false);
|
||||||
sentQuery = true;
|
sentQuery = true;
|
||||||
|
|
||||||
// Add abort function
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
expect(itemAborted).toEqual(false);
|
|
||||||
itemAborted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Do not do anything
|
// Do not do anything
|
||||||
},
|
},
|
||||||
(data, error) => {
|
(data, error) => {
|
||||||
@ -253,9 +235,6 @@ describe('Basic queries', () => {
|
|||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(0);
|
expect(status.queriesPending).toEqual(0);
|
||||||
|
|
||||||
// Item should have been aborted
|
|
||||||
expect(itemAborted).toEqual(true);
|
|
||||||
|
|
||||||
// Should have been config.rotate + config.timeout
|
// Should have been config.rotate + config.timeout
|
||||||
const diff = Date.now() - startTime;
|
const diff = Date.now() - startTime;
|
||||||
expect(diff).toBeGreaterThan(250);
|
expect(diff).toBeGreaterThan(250);
|
||||||
@ -272,4 +251,63 @@ describe('Basic queries', () => {
|
|||||||
|
|
||||||
isSync = false;
|
isSync = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Abort query', (done) => {
|
||||||
|
const payload = {};
|
||||||
|
const resources = ['api1', 'api2', 'api3'];
|
||||||
|
const config: RedundancyConfig = {
|
||||||
|
resources,
|
||||||
|
index: 0,
|
||||||
|
timeout: 200,
|
||||||
|
rotate: 100,
|
||||||
|
random: false,
|
||||||
|
dataAfterTimeout: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tracking
|
||||||
|
let isSync = true;
|
||||||
|
let sentQuery = false;
|
||||||
|
|
||||||
|
// Send query
|
||||||
|
const getStatus = sendQuery(
|
||||||
|
config,
|
||||||
|
payload,
|
||||||
|
(resource, queryPayload, callback) => {
|
||||||
|
expect(isSync).toEqual(false);
|
||||||
|
expect(resource).toEqual(resources[0]);
|
||||||
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
|
// Make sure query was executed only once
|
||||||
|
expect(sentQuery).toEqual(false);
|
||||||
|
sentQuery = true;
|
||||||
|
|
||||||
|
// Abort
|
||||||
|
callback('abort', 404);
|
||||||
|
},
|
||||||
|
(data, error) => {
|
||||||
|
// Make sure query was sent
|
||||||
|
expect(sentQuery).toEqual(true);
|
||||||
|
|
||||||
|
// Validate data
|
||||||
|
expect(data).toBeUndefined();
|
||||||
|
expect(error).toBe(404);
|
||||||
|
|
||||||
|
// Check status
|
||||||
|
const status = getStatus();
|
||||||
|
expect(status.status).toEqual('failed');
|
||||||
|
expect(status.queriesSent).toEqual(1);
|
||||||
|
expect(status.queriesPending).toEqual(0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check status
|
||||||
|
const status = getStatus();
|
||||||
|
expect(status.status).toEqual('pending');
|
||||||
|
expect(status.queriesSent).toEqual(0);
|
||||||
|
expect(status.queriesPending).toEqual(0);
|
||||||
|
|
||||||
|
isSync = false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ describe('Multiple resources', () => {
|
|||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(resource).toEqual('api1');
|
expect(resource).toEqual('api1');
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
@ -34,20 +34,14 @@ describe('Multiple resources', () => {
|
|||||||
sentQuery++;
|
sentQuery++;
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
expect(status.queriesSent).toEqual(1);
|
expect(status.queriesSent).toEqual(1);
|
||||||
expect(status.queriesPending).toEqual(1);
|
expect(status.queriesPending).toEqual(1);
|
||||||
|
|
||||||
// Add abort function
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done('Abort should have not been called');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
queryItem.done(result);
|
callback('success', result);
|
||||||
},
|
},
|
||||||
(data, error) => {
|
(data, error) => {
|
||||||
// Make sure query was sent
|
// Make sure query was sent
|
||||||
@ -68,9 +62,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(diff).toBeLessThan(50);
|
expect(diff).toBeLessThan(50);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
},
|
|
||||||
() => {
|
|
||||||
done('This should not have been called');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -100,14 +91,12 @@ describe('Multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let itemAborted = false;
|
|
||||||
let parentUpdated = false;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -116,7 +105,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -128,29 +116,15 @@ describe('Multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(sentQuery);
|
expect(status.queriesSent).toEqual(sentQuery);
|
||||||
expect(status.queriesPending).toEqual(sentQuery);
|
expect(status.queriesPending).toEqual(sentQuery);
|
||||||
|
|
||||||
// Add abort function
|
|
||||||
// Time out first, complete second
|
// Time out first, complete second
|
||||||
switch (sentQuery) {
|
switch (sentQuery) {
|
||||||
case 1:
|
case 1:
|
||||||
queryItem.abort = (): void => {
|
|
||||||
// First item should be aborted, but only once
|
|
||||||
expect(itemAborted).toEqual(false);
|
|
||||||
|
|
||||||
// When this is executed, counter should have been increased
|
|
||||||
expect(sentQuery).toEqual(2);
|
|
||||||
itemAborted = true;
|
|
||||||
|
|
||||||
// Do nothing, let it time out
|
// Do nothing, let it time out
|
||||||
};
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
queryItem.abort = (): void => {
|
|
||||||
done('Abort should have not been called');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send result
|
// Send result
|
||||||
queryItem.done(result);
|
callback('success', result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -161,9 +135,6 @@ describe('Multiple resources', () => {
|
|||||||
// Make sure queries were sent
|
// Make sure queries were sent
|
||||||
expect(sentQuery).toEqual(2);
|
expect(sentQuery).toEqual(2);
|
||||||
|
|
||||||
// First query should have been aborted
|
|
||||||
expect(itemAborted).toEqual(true);
|
|
||||||
|
|
||||||
// Validate data
|
// Validate data
|
||||||
expect(data).toEqual(result);
|
expect(data).toEqual(result);
|
||||||
expect(error).toBeUndefined();
|
expect(error).toBeUndefined();
|
||||||
@ -174,20 +145,12 @@ describe('Multiple resources', () => {
|
|||||||
expect(status.queriesSent).toEqual(2);
|
expect(status.queriesSent).toEqual(2);
|
||||||
expect(status.queriesPending).toEqual(0);
|
expect(status.queriesPending).toEqual(0);
|
||||||
|
|
||||||
// Parent should have been updated
|
|
||||||
expect(parentUpdated).toEqual(true);
|
|
||||||
|
|
||||||
// Delay between first and second queries
|
// Delay between first and second queries
|
||||||
const diff = Date.now() - startTime;
|
const diff = Date.now() - startTime;
|
||||||
expect(diff).toBeGreaterThan(50);
|
expect(diff).toBeGreaterThan(50);
|
||||||
expect(diff).toBeLessThan(150);
|
expect(diff).toBeLessThan(150);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
},
|
|
||||||
(newIndex) => {
|
|
||||||
// Start index should be updated to 1
|
|
||||||
expect(newIndex).toEqual(1);
|
|
||||||
parentUpdated = true;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -216,14 +179,12 @@ describe('Multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let item1Aborted = false;
|
|
||||||
let item2Aborted = false;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload, callback) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -232,7 +193,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(resource).toEqual(resources[sentQuery]);
|
expect(resource).toEqual(resources[sentQuery]);
|
||||||
|
|
||||||
// Check status
|
// Check status
|
||||||
expect(queryItem.getQueryStatus).toEqual(getStatus);
|
|
||||||
const status = getStatus();
|
const status = getStatus();
|
||||||
expect(status.status).toEqual('pending');
|
expect(status.status).toEqual('pending');
|
||||||
expect(status.payload).toEqual(payload);
|
expect(status.payload).toEqual(payload);
|
||||||
@ -247,29 +207,8 @@ describe('Multiple resources', () => {
|
|||||||
// Add abort functions
|
// Add abort functions
|
||||||
switch (sentQuery) {
|
switch (sentQuery) {
|
||||||
case 1:
|
case 1:
|
||||||
queryItem.abort = (): void => {
|
|
||||||
expect(item1Aborted).toEqual(false);
|
|
||||||
expect(item2Aborted).toEqual(false);
|
|
||||||
|
|
||||||
// This should have been executed at the end
|
|
||||||
expect(sentQuery).toEqual(2);
|
|
||||||
item1Aborted = true;
|
|
||||||
|
|
||||||
// Do not send anything
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
queryItem.abort = (): void => {
|
|
||||||
expect(item1Aborted).toEqual(true);
|
|
||||||
expect(item2Aborted).toEqual(false);
|
|
||||||
|
|
||||||
// This should have been executed at the end
|
|
||||||
expect(sentQuery).toEqual(2);
|
|
||||||
item2Aborted = true;
|
|
||||||
|
|
||||||
// Do not send anything
|
// Do not send anything
|
||||||
};
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -280,10 +219,6 @@ describe('Multiple resources', () => {
|
|||||||
// Make sure queries were sent
|
// Make sure queries were sent
|
||||||
expect(sentQuery).toEqual(2);
|
expect(sentQuery).toEqual(2);
|
||||||
|
|
||||||
// Queries should have been aborted
|
|
||||||
expect(item1Aborted).toEqual(true);
|
|
||||||
expect(item2Aborted).toEqual(true);
|
|
||||||
|
|
||||||
// Validate data
|
// Validate data
|
||||||
expect(data).toBeUndefined();
|
expect(data).toBeUndefined();
|
||||||
expect(error).toBeUndefined();
|
expect(error).toBeUndefined();
|
||||||
@ -300,9 +235,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(diff).toBeLessThan(120);
|
expect(diff).toBeLessThan(120);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
},
|
|
||||||
() => {
|
|
||||||
done('This should have never been called');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -331,14 +263,12 @@ describe('Multiple resources', () => {
|
|||||||
let isSync = true;
|
let isSync = true;
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let sentQuery = 0;
|
let sentQuery = 0;
|
||||||
let item1Aborted = false;
|
|
||||||
let item2Aborted = false;
|
|
||||||
|
|
||||||
// Send query
|
// Send query
|
||||||
const getStatus = sendQuery(
|
const getStatus = sendQuery(
|
||||||
config,
|
config,
|
||||||
payload,
|
payload,
|
||||||
(resource, queryPayload, queryItem) => {
|
(resource, queryPayload) => {
|
||||||
expect(isSync).toEqual(false);
|
expect(isSync).toEqual(false);
|
||||||
expect(queryPayload).toEqual(payload);
|
expect(queryPayload).toEqual(payload);
|
||||||
|
|
||||||
@ -348,33 +278,11 @@ describe('Multiple resources', () => {
|
|||||||
|
|
||||||
// Bump counter
|
// Bump counter
|
||||||
sentQuery++;
|
sentQuery++;
|
||||||
|
|
||||||
// Add abort functions
|
|
||||||
switch (sentQuery) {
|
|
||||||
case 1:
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
item1Aborted = true;
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
queryItem.abort = (): void => {
|
|
||||||
item2Aborted = true;
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
done('This code should not have been reached');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
(data, error) => {
|
(data, error) => {
|
||||||
// Make sure queries were sent
|
// Make sure queries were sent
|
||||||
expect(sentQuery).toEqual(2);
|
expect(sentQuery).toEqual(2);
|
||||||
|
|
||||||
// Queries should have been aborted
|
|
||||||
expect(item1Aborted).toEqual(true);
|
|
||||||
expect(item2Aborted).toEqual(true);
|
|
||||||
|
|
||||||
// Validate data
|
// Validate data
|
||||||
expect(data).toBeUndefined();
|
expect(data).toBeUndefined();
|
||||||
expect(error).toBeUndefined();
|
expect(error).toBeUndefined();
|
||||||
@ -385,9 +293,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(diff).toBeLessThan(120);
|
expect(diff).toBeLessThan(120);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
},
|
|
||||||
() => {
|
|
||||||
done('This should have never been called');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -448,9 +353,6 @@ describe('Multiple resources', () => {
|
|||||||
expect(diff).toBeLessThan(170);
|
expect(diff).toBeLessThan(170);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
},
|
|
||||||
() => {
|
|
||||||
done('This should have never been called');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ describe('Redundancy class', () => {
|
|||||||
|
|
||||||
const query = redundancy.query(
|
const query = redundancy.query(
|
||||||
'/foo',
|
'/foo',
|
||||||
(resource, payload, status) => {
|
(resource, payload, callback) => {
|
||||||
counter++;
|
counter++;
|
||||||
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
expect(counter).toBeLessThan(3); // No more than 2 queries should be executed
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ describe('Redundancy class', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do something with "data", simulate instant callback
|
// Do something with "data", simulate instant callback
|
||||||
status.done(responses[uri]);
|
callback('success', responses[uri]);
|
||||||
|
|
||||||
// Complete test
|
// Complete test
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -80,7 +80,9 @@ describe('Redundancy class', () => {
|
|||||||
};
|
};
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
const query = redundancy.query('/foo', (resource, payload, status) => {
|
const query = redundancy.query(
|
||||||
|
'/foo',
|
||||||
|
(resource, payload, callback) => {
|
||||||
counter++;
|
counter++;
|
||||||
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
expect(counter).toBeLessThan(2); // Should be success on first call because start index = 1
|
||||||
|
|
||||||
@ -93,7 +95,7 @@ describe('Redundancy class', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do something with "data", simulate instant callback
|
// Do something with "data", simulate instant callback
|
||||||
status.done(responses[uri]);
|
callback('success', responses[uri]);
|
||||||
|
|
||||||
// Complete test
|
// Complete test
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -102,7 +104,8 @@ describe('Redundancy class', () => {
|
|||||||
expect(redundancy.getIndex()).toEqual(1);
|
expect(redundancy.getIndex()).toEqual(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Test find()
|
// Test find()
|
||||||
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
expect(redundancy.find((item) => item().payload === '/foo')).toEqual(
|
||||||
|
@ -46,7 +46,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
return [item];
|
return [item];
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendQuery = (host, params, item) => {
|
const sendQuery = (host, params, callback) => {
|
||||||
// This callback should be called after prepareQuery
|
// This callback should be called after prepareQuery
|
||||||
expect(asyncCounter).toBe(2);
|
expect(asyncCounter).toBe(2);
|
||||||
asyncCounter++;
|
asyncCounter++;
|
||||||
@ -64,7 +64,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(params).toEqual(expected);
|
expect(params).toEqual(expected);
|
||||||
|
|
||||||
// Send data
|
// Send data
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -170,7 +170,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let queryCounter = 0;
|
let queryCounter = 0;
|
||||||
const sendQuery = (host, params, item) => {
|
const sendQuery = (host, params, callback) => {
|
||||||
// Test input
|
// Test input
|
||||||
expect(host).toBe('https://api1.local');
|
expect(host).toBe('https://api1.local');
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
body: '<path d="" />',
|
body: '<path d="" />',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons,
|
icons,
|
||||||
// Test mismatched provider: should be ignored because provider name is not affected by actual API response
|
// Test mismatched provider: should be ignored because provider name is not affected by actual API response
|
||||||
@ -263,7 +263,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let queryCounter = 0;
|
let queryCounter = 0;
|
||||||
const sendQuery = (host, params, item) => {
|
const sendQuery = (host, params, callback) => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
params;
|
params;
|
||||||
switch (queryCounter) {
|
switch (queryCounter) {
|
||||||
@ -279,7 +279,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -359,7 +359,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let queryCounter = 0;
|
let queryCounter = 0;
|
||||||
const sendQuery = (host, params, item) => {
|
const sendQuery = (host, params, callback) => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
|
|
||||||
expect(params.type).toBe('icons');
|
expect(params.type).toBe('icons');
|
||||||
@ -382,7 +382,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -401,7 +401,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon3: {
|
icon3: {
|
||||||
@ -514,7 +514,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let queryCounter = 0;
|
let queryCounter = 0;
|
||||||
const sendQuery = (host, params, item) => {
|
const sendQuery = (host, params, callback) => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
|
|
||||||
expect(params.type).toBe('icons');
|
expect(params.type).toBe('icons');
|
||||||
@ -539,7 +539,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix: params.prefix,
|
prefix: params.prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -559,7 +559,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix: params.prefix,
|
prefix: params.prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon2: {
|
icon2: {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { PendingQueryItem } from '@iconify/api-redundancy';
|
import type { QueryModuleResponse } from '@iconify/api-redundancy';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Params for sendQuery()
|
* Params for sendQuery()
|
||||||
@ -31,7 +31,7 @@ export type IconifyAPIPrepareIconsQuery = (
|
|||||||
export type IconifyAPISendQuery = (
|
export type IconifyAPISendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
status: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { PendingQueryItem } from '@iconify/api-redundancy';
|
import type { QueryModuleResponse } from '@iconify/api-redundancy';
|
||||||
import type {
|
import type {
|
||||||
IconifyAPIQueryParams,
|
IconifyAPIQueryParams,
|
||||||
IconifyAPIPrepareIconsQuery,
|
IconifyAPIPrepareIconsQuery,
|
||||||
@ -106,6 +106,13 @@ function calculateMaxLength(provider: string, prefix: string): number {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should query be aborted, based on last HTTP status
|
||||||
|
*/
|
||||||
|
function shouldAbort(status: number): boolean {
|
||||||
|
return status === 404;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare params
|
* Prepare params
|
||||||
*/
|
*/
|
||||||
@ -178,11 +185,11 @@ function getPath(provider?: string): string {
|
|||||||
const send: IconifyAPISendQuery = (
|
const send: IconifyAPISendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
status: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
if (!fetchModule) {
|
if (!fetchModule) {
|
||||||
// Fail: return "424 Failed Dependency" (its not meant to be used like that, but it is the closest match)
|
// Fail: return "424 Failed Dependency" (its not meant to be used like that, but it is the closest match)
|
||||||
status.done(void 0, 424);
|
callback('abort', 424);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +215,7 @@ const send: IconifyAPISendQuery = (
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// Fail: return 400 Bad Request
|
// Fail: return 400 Bad Request
|
||||||
status.done(void 0, 400);
|
callback('abort', 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,10 +225,11 @@ const send: IconifyAPISendQuery = (
|
|||||||
// console.log('API query:', host + path);
|
// console.log('API query:', host + path);
|
||||||
fetchModule(host + path)
|
fetchModule(host + path)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status !== 200) {
|
const status = response.status;
|
||||||
|
if (status !== 200) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Complete on next tick to get out of try...catch
|
// Complete on next tick to get out of try...catch
|
||||||
status.done(void 0, response.status);
|
callback(shouldAbort(status) ? 'abort' : 'next', status);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -234,7 +242,7 @@ const send: IconifyAPISendQuery = (
|
|||||||
if (typeof data !== 'object' || data === null) {
|
if (typeof data !== 'object' || data === null) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Complete on next tick to get out of try...catch
|
// Complete on next tick to get out of try...catch
|
||||||
status.done(void 0, defaultError);
|
callback('next', defaultError);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -242,11 +250,11 @@ const send: IconifyAPISendQuery = (
|
|||||||
// Store cache and complete on next tick
|
// Store cache and complete on next tick
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Complete on next tick to get out of try...catch
|
// Complete on next tick to get out of try...catch
|
||||||
status.done(data);
|
callback('success', data);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
status.done(void 0, defaultError);
|
callback('next', defaultError);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { PendingQueryItem } from '@iconify/api-redundancy';
|
import type { QueryModuleResponse } from '@iconify/api-redundancy';
|
||||||
import type {
|
import type {
|
||||||
IconifyAPIQueryParams,
|
IconifyAPIQueryParams,
|
||||||
IconifyAPIPrepareIconsQuery,
|
IconifyAPIPrepareIconsQuery,
|
||||||
@ -104,6 +104,7 @@ function calculateMaxLength(provider: string, prefix: string): number {
|
|||||||
// Get available length
|
// Get available length
|
||||||
const url = mergeParams(prefix + '.js', {
|
const url = mergeParams(prefix + '.js', {
|
||||||
icons: '',
|
icons: '',
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
callback: rootVarName!,
|
callback: rootVarName!,
|
||||||
});
|
});
|
||||||
result =
|
result =
|
||||||
@ -170,11 +171,11 @@ const prepare: IconifyAPIPrepareIconsQuery = (
|
|||||||
const send: IconifyAPISendQuery = (
|
const send: IconifyAPISendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
status: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
if (params.type !== 'icons') {
|
if (params.type !== 'icons') {
|
||||||
// JSONP supports only icons
|
// JSONP supports only icons
|
||||||
status.done(void 0, 400);
|
callback('abort', 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +202,7 @@ const send: IconifyAPISendQuery = (
|
|||||||
|
|
||||||
const url = mergeParams(prefix + '.js', {
|
const url = mergeParams(prefix + '.js', {
|
||||||
icons: iconsList,
|
icons: iconsList,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
callback: rootVarName!.replace('{cb}', callbackName),
|
callback: rootVarName!.replace('{cb}', callbackName),
|
||||||
});
|
});
|
||||||
const path = pathCache[cacheKey] + url;
|
const path = pathCache[cacheKey] + url;
|
||||||
@ -208,7 +210,7 @@ const send: IconifyAPISendQuery = (
|
|||||||
global[callbackName] = (data: unknown): void => {
|
global[callbackName] = (data: unknown): void => {
|
||||||
// Remove callback and complete query
|
// Remove callback and complete query
|
||||||
delete global[callbackName];
|
delete global[callbackName];
|
||||||
status.done(data);
|
callback('success', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create URI
|
// Create URI
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars-experimental */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import type { PendingQueryItem } from '@iconify/api-redundancy';
|
import type { QueryModuleResponse } from '@iconify/api-redundancy';
|
||||||
import type {
|
import type {
|
||||||
IconifyAPIIconsQueryParams,
|
IconifyAPIIconsQueryParams,
|
||||||
IconifyAPIQueryParams,
|
IconifyAPIQueryParams,
|
||||||
@ -252,7 +251,7 @@ export const mockAPIModule: IconifyAPIModule = {
|
|||||||
send: (
|
send: (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
status: PendingQueryItem
|
queryCallback: QueryModuleResponse
|
||||||
) => {
|
) => {
|
||||||
const provider = params.provider;
|
const provider = params.provider;
|
||||||
let data: IconifyMockAPI;
|
let data: IconifyMockAPI;
|
||||||
@ -261,7 +260,7 @@ export const mockAPIModule: IconifyAPIModule = {
|
|||||||
case 'icons': {
|
case 'icons': {
|
||||||
if (provider === void 0) {
|
if (provider === void 0) {
|
||||||
// Fail: return 400 Bad Request
|
// Fail: return 400 Bad Request
|
||||||
status.done(void 0, 400);
|
queryCallback('abort', 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const index = (params as MockAPIIconsQueryParams).index;
|
const index = (params as MockAPIIconsQueryParams).index;
|
||||||
@ -280,12 +279,12 @@ export const mockAPIModule: IconifyAPIModule = {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// Fail: return 400 Bad Request
|
// Fail: return 400 Bad Request
|
||||||
status.done(void 0, 400);
|
queryCallback('abort', 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data === void 0) {
|
if (data === void 0) {
|
||||||
status.done(void 0, 404);
|
queryCallback('abort', 404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,11 +307,10 @@ export const mockAPIModule: IconifyAPIModule = {
|
|||||||
|
|
||||||
// Run after delay
|
// Run after delay
|
||||||
callback(() => {
|
callback(() => {
|
||||||
if (typeof data.response === 'number') {
|
queryCallback(
|
||||||
status.done(void 0, data.response);
|
typeof data.response === 'number' ? 'next' : 'success',
|
||||||
} else {
|
data.response
|
||||||
status.done(data.response);
|
);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { PendingQueryItem } from '@iconify/api-redundancy';
|
import type { QueryModuleResponse } from '@iconify/api-redundancy';
|
||||||
import { addAPIProvider } from '../../lib/api/config';
|
import { addAPIProvider } from '../../lib/api/config';
|
||||||
import type {
|
import type {
|
||||||
IconifyAPIIconsQueryParams,
|
IconifyAPIIconsQueryParams,
|
||||||
@ -58,7 +58,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
// This callback should be called after prepareQuery
|
// This callback should be called after prepareQuery
|
||||||
expect(asyncCounter).toBe(2);
|
expect(asyncCounter).toBe(2);
|
||||||
@ -77,7 +77,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(params).toEqual(expected);
|
expect(params).toEqual(expected);
|
||||||
|
|
||||||
// Send data
|
// Send data
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -191,7 +191,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
expect(params.type).toBe('icons');
|
expect(params.type).toBe('icons');
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(params).toEqual(expected);
|
expect(params).toEqual(expected);
|
||||||
|
|
||||||
// Send data
|
// Send data
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -265,7 +265,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
expect(params.type).toBe('icons');
|
expect(params.type).toBe('icons');
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(params).toEqual(expected);
|
expect(params).toEqual(expected);
|
||||||
|
|
||||||
// Send data
|
// Send data
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -351,7 +351,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
// Test input
|
// Test input
|
||||||
expect(host).toBe('https://api1.local');
|
expect(host).toBe('https://api1.local');
|
||||||
@ -378,7 +378,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
body: '<path d="" />',
|
body: '<path d="" />',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons,
|
icons,
|
||||||
// Test mismatched provider: should be ignored because provider name is not affected by actual API response
|
// Test mismatched provider: should be ignored because provider name is not affected by actual API response
|
||||||
@ -452,7 +452,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
params;
|
params;
|
||||||
@ -469,7 +469,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -556,7 +556,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
|
|
||||||
@ -580,7 +580,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -599,7 +599,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix,
|
prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon3: {
|
icon3: {
|
||||||
@ -719,7 +719,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
const sendQuery = (
|
const sendQuery = (
|
||||||
host: string,
|
host: string,
|
||||||
params: IconifyAPIQueryParams,
|
params: IconifyAPIQueryParams,
|
||||||
item: PendingQueryItem
|
callback: QueryModuleResponse
|
||||||
): void => {
|
): void => {
|
||||||
queryCounter++;
|
queryCounter++;
|
||||||
|
|
||||||
@ -745,7 +745,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix: params.prefix,
|
prefix: params.prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon1: {
|
icon1: {
|
||||||
@ -765,7 +765,7 @@ describe('Testing API loadIcons', () => {
|
|||||||
expect(host).toBe('https://api2.local');
|
expect(host).toBe('https://api2.local');
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
item.done({
|
callback('success', {
|
||||||
prefix: params.prefix,
|
prefix: params.prefix,
|
||||||
icons: {
|
icons: {
|
||||||
icon2: {
|
icon2: {
|
||||||
|
@ -353,4 +353,47 @@ describe('Testing mock API module', () => {
|
|||||||
|
|
||||||
isSync = false;
|
isSync = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('not_found response', (done) => {
|
||||||
|
const prefix = nextPrefix();
|
||||||
|
|
||||||
|
mockAPIData({
|
||||||
|
type: 'icons',
|
||||||
|
provider,
|
||||||
|
prefix,
|
||||||
|
icons: ['test1', 'test2'],
|
||||||
|
response: {
|
||||||
|
prefix,
|
||||||
|
icons: {},
|
||||||
|
not_found: ['test1', 'test2'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let isSync = true;
|
||||||
|
|
||||||
|
loadIcons(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
provider,
|
||||||
|
prefix,
|
||||||
|
name: 'test1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
(loaded, missing, pending) => {
|
||||||
|
expect(isSync).toBe(false);
|
||||||
|
expect(loaded).toEqual([]);
|
||||||
|
expect(pending).toEqual([]);
|
||||||
|
expect(missing).toEqual([
|
||||||
|
{
|
||||||
|
provider,
|
||||||
|
prefix,
|
||||||
|
name: 'test1',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
isSync = false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -173,8 +173,17 @@ export function validateIconSet(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check not_found
|
||||||
|
if (data.not_found !== void 0 && !(data.not_found instanceof Array)) {
|
||||||
|
if (fix) {
|
||||||
|
delete data.not_found;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid not_found list');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure icons list is not empty
|
// Make sure icons list is not empty
|
||||||
if (!Object.keys(data.icons).length) {
|
if (!Object.keys(data.icons).length && !data.not_found?.length) {
|
||||||
throw new Error('Icon set is empty');
|
throw new Error('Icon set is empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user