created lots of tests
This commit is contained in:
parent
42baadae38
commit
54f37f9521
21 changed files with 4577 additions and 215 deletions
171
libs/core/queue/test/batch-processor.test.ts
Normal file
171
libs/core/queue/test/batch-processor.test.ts
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import { describe, expect, it, mock } from 'bun:test';
|
||||
import { processBatchJob, processItems } from '../src/batch-processor';
|
||||
import type { BatchJobData } from '../src/types';
|
||||
|
||||
describe('Batch Processor', () => {
|
||||
const mockLogger = {
|
||||
info: mock(() => {}),
|
||||
error: mock(() => {}),
|
||||
warn: mock(() => {}),
|
||||
debug: mock(() => {}),
|
||||
trace: mock(() => {}),
|
||||
};
|
||||
|
||||
describe('processBatchJob', () => {
|
||||
it('should process all items successfully', async () => {
|
||||
const batchData: BatchJobData = {
|
||||
items: ['item1', 'item2', 'item3'],
|
||||
options: {
|
||||
batchSize: 2,
|
||||
concurrency: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const processor = mock((item: string) => Promise.resolve({ processed: item }));
|
||||
|
||||
const result = await processBatchJob(batchData, processor, mockLogger);
|
||||
|
||||
expect(result.totalItems).toBe(3);
|
||||
expect(result.successful).toBe(3);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(result.errors).toHaveLength(0);
|
||||
expect(processor).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('should handle partial failures', async () => {
|
||||
const batchData: BatchJobData = {
|
||||
items: ['item1', 'item2', 'item3'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
const processor = mock((item: string) => {
|
||||
if (item === 'item2') {
|
||||
return Promise.reject(new Error('Processing failed'));
|
||||
}
|
||||
return Promise.resolve({ processed: item });
|
||||
});
|
||||
|
||||
const result = await processBatchJob(batchData, processor, mockLogger);
|
||||
|
||||
expect(result.totalItems).toBe(3);
|
||||
expect(result.successful).toBe(2);
|
||||
expect(result.failed).toBe(1);
|
||||
expect(result.errors).toHaveLength(1);
|
||||
expect(result.errors[0].item).toBe('item2');
|
||||
expect(result.errors[0].error).toBe('Processing failed');
|
||||
});
|
||||
|
||||
it('should handle empty items', async () => {
|
||||
const batchData: BatchJobData = {
|
||||
items: [],
|
||||
options: {},
|
||||
};
|
||||
|
||||
const processor = mock(() => Promise.resolve({}));
|
||||
|
||||
const result = await processBatchJob(batchData, processor, mockLogger);
|
||||
|
||||
expect(result.totalItems).toBe(0);
|
||||
expect(result.successful).toBe(0);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(processor).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should track duration', async () => {
|
||||
const batchData: BatchJobData = {
|
||||
items: ['item1'],
|
||||
options: {},
|
||||
};
|
||||
|
||||
const processor = mock(() =>
|
||||
new Promise(resolve => setTimeout(() => resolve({}), 10))
|
||||
);
|
||||
|
||||
const result = await processBatchJob(batchData, processor, mockLogger);
|
||||
|
||||
expect(result.duration).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('processItems', () => {
|
||||
it('should process items with default options', async () => {
|
||||
const items = [1, 2, 3, 4, 5];
|
||||
const processor = mock((item: number) => Promise.resolve(item * 2));
|
||||
|
||||
const results = await processItems(items, processor);
|
||||
|
||||
expect(results).toEqual([2, 4, 6, 8, 10]);
|
||||
expect(processor).toHaveBeenCalledTimes(5);
|
||||
});
|
||||
|
||||
it('should process items in batches', async () => {
|
||||
const items = [1, 2, 3, 4, 5];
|
||||
const processor = mock((item: number) => Promise.resolve(item * 2));
|
||||
|
||||
const results = await processItems(items, processor, {
|
||||
batchSize: 2,
|
||||
concurrency: 1,
|
||||
});
|
||||
|
||||
expect(results).toEqual([2, 4, 6, 8, 10]);
|
||||
expect(processor).toHaveBeenCalledTimes(5);
|
||||
});
|
||||
|
||||
it('should handle concurrent processing', async () => {
|
||||
const items = [1, 2, 3, 4];
|
||||
let activeCount = 0;
|
||||
let maxActiveCount = 0;
|
||||
|
||||
const processor = mock(async (item: number) => {
|
||||
activeCount++;
|
||||
maxActiveCount = Math.max(maxActiveCount, activeCount);
|
||||
await new Promise(resolve => setTimeout(resolve, 10));
|
||||
activeCount--;
|
||||
return item * 2;
|
||||
});
|
||||
|
||||
await processItems(items, processor, {
|
||||
batchSize: 10,
|
||||
concurrency: 2,
|
||||
});
|
||||
|
||||
// With concurrency 2, at most 2 items should be processed at once
|
||||
expect(maxActiveCount).toBeLessThanOrEqual(2);
|
||||
expect(processor).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
|
||||
it('should handle empty array', async () => {
|
||||
const processor = mock(() => Promise.resolve({}));
|
||||
const results = await processItems([], processor);
|
||||
|
||||
expect(results).toEqual([]);
|
||||
expect(processor).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should propagate errors', async () => {
|
||||
const items = [1, 2, 3];
|
||||
const processor = mock((item: number) => {
|
||||
if (item === 2) {
|
||||
return Promise.reject(new Error('Process error'));
|
||||
}
|
||||
return Promise.resolve(item);
|
||||
});
|
||||
|
||||
await expect(processItems(items, processor)).rejects.toThrow('Process error');
|
||||
});
|
||||
|
||||
it('should process large batches efficiently', async () => {
|
||||
const items = Array.from({ length: 100 }, (_, i) => i);
|
||||
const processor = mock((item: number) => Promise.resolve(item + 1));
|
||||
|
||||
const results = await processItems(items, processor, {
|
||||
batchSize: 20,
|
||||
concurrency: 5,
|
||||
});
|
||||
|
||||
expect(results).toHaveLength(100);
|
||||
expect(results[0]).toBe(1);
|
||||
expect(results[99]).toBe(100);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue