import { executePromisesLimited } from './promise-utils';

describe('PromiseUtils', () => {
  describe('executePromisesLimited', () => {
    it('Should execute a list of promises with a length below the concurrency limit', async () => {
      // Arrange
      const numbers = [0, 1, 2, 3, 4];

      // Act
      const result = await executePromisesLimited<number>(numbers.map(async (num) => {
        return num + 1;
      }), 10);

      // Assert
      expect(result).toEqual([1, 2, 3, 4, 5]);
    });

    it('Should not change the original input', async () => {
      // Arrange
      const numbers = [0, 1, 2, 3, 4];

      // Act
      await executePromisesLimited<number>(numbers.map(async (num) => {
        return num + 1;
      }), 10);

      // Assert
      expect(numbers).toEqual([0, 1, 2, 3, 4]);
    });

    it('Should execute a list of promises above the with a length above the concurrency limit', async () => {
      // Arrange
      const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

      // Act
      const result = await executePromisesLimited<number>(numbers.map(async (num) => {
        return num + 1;
      }), 10);

      // Assert
      expect(result).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
    });

    it('Should handle a list of promises', async () => {
      // Arrange
      const increase = async (num: number): Promise<number> => num + 1;
      const promises: Promise<number>[] = [];
      for (let i = 0; i < 10; i++) {
        promises.push(increase(i));
      }

      // Act
      const result = await executePromisesLimited<number>(promises, 2);

      // Assert
      expect(result).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    });
  });
});
