const { Node, LinkedList } = require('.'); describe('Data Structures: Linked Lists', () => { describe('Node of a List', () => { it('Should be a class', () => { expect(typeof Node.prototype.constructor).toEqual('function'); }); it('Should set the data and next field of a node', () => { const node = new Node('Hello', null); expect(node.data).toEqual('Hello'); expect(node.next).toEqual(null); }); }); describe('LinkedList Instance', () => { it('Should be a class', () => { expect(typeof LinkedList.prototype.constructor).toEqual('function'); }); it('Should set the data and next field of a node', () => { const list = new LinkedList(); expect(list.head).not.toEqual(undefined); expect(list.head).toEqual(null); }); }); describe('LinkedList API', () => { let list = new LinkedList(); beforeEach(() => { list = new LinkedList(); }); describe('addAtBeginning(value)', () => { it('Should add element at beginning', () => { list.addAtBeginning(12); expect(list.head.data).toEqual(12); list.addAtBeginning(15); expect(list.head.data).toEqual(15); }); it('Should return the 10 as the first element in the list', () => { list.addAtBeginning(10); expect(list.getFirst().data).toEqual(10); }); }); describe('addAtEnd(value)', () => { it('Should add element at end', () => { list.addAtBeginning(10); list.addAtEnd(12); expect(list.getLast().data).toEqual(12); }); it('Should add at the beginning if the list is empty', () => { list.addAtEnd(15); expect(list.head.data).toEqual(15); expect(list.head.next).toEqual(null); }); it('Should return 4 as length of the list after adding at the end', () => { list.addAtEnd(15); list.addAtEnd(23); list.addAtEnd(33); list.addAtEnd(10); expect(list.length()).toEqual(4); expect(list.traverseList()).toEqual([15, 23, 33, 10]); }); }); describe('length() of the list', () => { it('Should return 0 if the list is empty', () => { expect(list.length()).toEqual(0); }); it('Should return the present size of the list after adding elements', () => { list.addAtBeginning(1); list.addAtBeginning(2); list.addAtBeginning(3); expect(list.length()).toEqual(3); }); it('Should return the present size of the list after removing elements', () => { list.addAtBeginning(1); list.addAtBeginning(2); list.addAtBeginning(3); expect(list.length()).toEqual(3); list.removeFromEnd(); list.removeFromBeginning(); expect(list.length()).toEqual(1); }); }); describe('removeFromBeginning()', () => { it('Should remove element at front', () => { list.addAtBeginning(12); expect(list.removeFromBeginning().data).toEqual(12); expect(list.length()).toEqual(0); }); it('Should return the element after removing it', () => { list.addAtBeginning(15); list.addAtBeginning(16); expect(list.removeFromBeginning().data).toEqual(16); }); it('Should not throw error if the list is empty', () => { expect(() => list.removeFromBeginning()).not.toThrow(); }); }); describe('removeFromEnd()', () => { it('Should return `null` for empty list', () => { expect(list.removeFromEnd()).toEqual(null); }); it('Should remove element at last', () => { list.addAtBeginning('Hello'); list.addAtBeginning(14); list.addAtEnd(15); expect(list.removeFromEnd().data).toEqual(15); }); it('Should reduce the lengh of the list', () => { list.addAtBeginning(14); list.addAtEnd(15); expect(list.length()).toEqual(2); list.removeFromEnd(); expect(list.length()).toEqual(1); }); it('Should return the last element after removing it', () => { list.addAtBeginning(14); list.addAtEnd(15); expect(list.removeFromEnd().data).toEqual(15); }); }); describe('getLast()', () => { it('Should return `null` if the list is empty', () => { expect(list.getLast()).toEqual(null); }); it('Should return 10 as the last item in the list', () => { list.addAtEnd(15); list.addAtEnd(23); list.addAtEnd(33); list.addAtEnd(10); expect(list.getLast().data).toEqual(10); }); }); describe('getFirst()', () => { it('Should return `null` if the list is empty', () => { expect(list.getFirst()).toEqual(null); }); it('Should return 15 as the last item in the list', () => { list.addAtBeginning(15); list.addAtEnd(23); list.addAtEnd(33); list.addAtEnd(10); expect(list.getFirst().data).toEqual(15); }); }); describe('Get/Add/Remove at specific positions', () => { beforeEach(() => { list.addAtBeginning('Hello'); list.addAtEnd('There!'); list.addAtEnd('Welcome'); }); describe('getAt(index)', () => { it('Should return `null` for empty list regardless of index value', () => { list.delete(); expect(list.getAt(10)).toEqual(null); }); it('Should return the node for given index', () => { expect(list.getAt(1).data).toEqual('There!'); }); it('Should return the last element for large index', () => { expect(list.getAt(10).data).toEqual('Welcome'); }); }); describe('addAt(index, value)', () => { it('Should add at the beginning of empty list', () => { list.delete(); list.addAt(10, 'Boom'); expect(list.getFirst().data).toEqual('Boom'); }); it('Should add at the end of the list if the index is out of bound', () => { list.addAtEnd(1010); list.addAt(10, 'Boom'); expect(list.getLast().data).toEqual('Boom'); }); it('Should add new element at the given position', () => { list.addAt(2, 'Stranger'); expect(list.getAt(2).data).toEqual('Stranger'); expect(list.getAt(1).data).toEqual('There!'); expect(list.getAt(0).data).toEqual('Hello'); }); }); describe('removeAt(index)', () => { it('Should return null for empty list', () => { list.delete(); expect(list.removeAt(10)).toEqual(null); }); it('Should remove and return last element for large index value', () => { expect(list.removeAt(10).data).toEqual('Welcome'); }); it('Should remove and return the element at given index value', () => { list.delete(); [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(el => list.addAtBeginning(el)); expect(list.removeAt(10).data).toEqual(1); expect(list.removeAt(0).data).toEqual(9); expect(list.removeAt(5).data).toEqual(3); }); }); }); }); });