import { List } from './List';

describe('List', function () {
  test('should initialize empty', () => {
    const list = new List();
    expect(list.length).toBe(0);
  });
  test('should initialize with values', () => {
    const list = new List([{ id: '1' }, { id: '2' }]);
    expect(list.length).toBe(2);
  });
  test('should add array of values', () => {
    const list = new List();
    list.set([{ id: '1' }, { id: '2' }]);
    expect(list.length).toBe(2);
  });
  test('should add a single value', () => {
    const list = new List();
    list.set({ id: '1' });
    expect(list.length).toBe(1);
  });
  test('should get an item by id', () => {
    const list = new List([{ id: '1' }, { id: '2' }]);
    expect(list.get('1')).toBeDefined();
  });

  test('should get an item by index', () => {
    const list = new List([{ id: '1' }, { id: '2' }]);
    expect(list.get(0)).toBeDefined();
    expect(list.get(0)?.id).toBe('1');
  });

  test('should return undefined if an item index does not exist', () => {
    const list = new List([{ id: '1' }, { id: '2' }]);
    expect(list.get(10)).toBeUndefined();
  });

  test('should return undefined if item not found', () => {
    const list = new List([{ id: '1' }, { id: '2' }]);
    expect(list.get('3')).toBeUndefined();
  });
  test('should swap two items', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    list.swap(0, 2);
    expect(list.values[0].id).toBe('3');
    expect(list.values[2].id).toBe('1');
  });
  test('should swap two items by id', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    list.swapById('1', '3');
    expect(list.values[0].id).toBe('3');
    expect(list.values[2].id).toBe('1');
  });
  test('should delete an item', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    list.delete('1');

    expect(list.length).toBe(2);
    expect(list.get('1')).toBeUndefined();
  });

  test('should return values', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    expect(list.values).toEqual([{ id: '1' }, { id: '2' }, { id: '3' }]);
  });
  test('should return length', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    expect(list.length).toEqual(3);
  });

  test('should return false if item is not deleted', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    expect(list.delete('4')).toBe(false);
  });
  test('should return true if item is deleted', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    expect(list.delete('1')).toBe(true);
  });

  test('should reset the list', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    list.reset();
    expect(list.length).toBe(0);
  });

  test('pop should delete last item and return it', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    const item = list.pop();
    expect(list.length).toBe(2);
    expect(item).toEqual({ id: '3' });
  });

  test('pop should return undefined if list is empty', () => {
    const list = new List();
    const item = list.pop();
    expect(list.length).toBe(0);
    expect(item).toBeUndefined();
  });

  test('shift should delete first item and return it', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    const item = list.shift();
    expect(list.length).toBe(2);
    expect(item).toEqual({ id: '1' });
  });

  test('shift should return undefined if list is empty', () => {
    const list = new List();
    const item = list.shift();
    expect(list.length).toBe(0);
    expect(item).toBeUndefined();
  });

  test('peakFirst should return first item', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    const item = list.peakFirst();
    expect(list.length).toBe(3);
    expect(item).toEqual({ id: '1' });
  });

  test('peakLast: should return undefined if list is empty', () => {
    const list = new List();
    const item = list.peakLast();
    expect(list.length).toBe(0);
    expect(item).toBeUndefined();
  });

  test('peakLast should return last item', () => {
    const list = new List([{ id: '1' }, { id: '2' }, { id: '3' }]);
    const item = list.peakLast();
    expect(list.length).toBe(3);
    expect(item).toEqual({ id: '3' });
  });

  test('peakFirst: should return undefined if list is empty', () => {
    const list = new List();
    const item = list.peakFirst();
    expect(list.length).toBe(0);
    expect(item).toBeUndefined();
  });
});
