sangja
Version:
JavaScript data structures library
344 lines (291 loc) • 11.5 kB
JavaScript
/* eslint-env node, mocha */
const { assert } = require('chai');
const { LinkedList } = require('../src/index');
describe('LinkedList', () => {
describe('Constructor', () => {
it('Fails without new', () => {
assert.throws(() => LinkedList(), TypeError);
});
it('Deep equal empty instances', () => {
assert.deepEqual(new LinkedList(), new LinkedList());
});
it('Constructor with iterable', () => {
const list = new LinkedList([8, 8, 3, 1]);
assert.deepEqual([...list], [8, 8, 3, 1]);
});
});
describe('Basic Methods', () => {
let linkedList = null;
beforeEach(() => {
linkedList = new LinkedList();
});
it('add and get', () => {
assert.equal(linkedList.size(), 0);
linkedList.add(0, 12);
assert.equal(linkedList.size(), 1);
linkedList.add(0, 34);
assert.equal(linkedList.size(), 2);
linkedList.add(1, 56);
assert.equal(linkedList.size(), 3);
linkedList.add(1, 78);
assert.equal(linkedList.size(), 4);
linkedList.add(4, 123);
assert.equal(linkedList.size(), 5);
linkedList.add(4, 456);
assert.equal(linkedList.size(), 6);
// 34 - 78 - 56 - 12 - 456 - 123
assert.equal(linkedList.get(-2), undefined);
assert.equal(linkedList.get(-1), undefined);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(7), undefined);
assert.equal(linkedList.get(8), undefined);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(0), 34);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(1), 78);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(2), 56);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(3), 12);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(4), 456);
assert.equal(linkedList.size(), 6);
assert.equal(linkedList.get(5), 123);
assert.equal(linkedList.size(), 6);
assert.throws(() => linkedList.add(-1, 789), RangeError);
assert.throws(() => linkedList.add(7, 789), RangeError);
assert.throws(() => linkedList.add(8, 789), RangeError);
linkedList.clear();
assert.equal(linkedList.size(), 0);
linkedList.add(0, 1);
linkedList.add(1, 2);
assert.deepEqual([...linkedList], [1, 2]);
linkedList.add(4);
linkedList.add(3);
assert.deepEqual([...linkedList], [1, 2, 4, 3]);
assert.equal(linkedList.get(), undefined);
});
it('addAll', () => {
linkedList.add(0, 12);
linkedList.add(1, 34);
assert.deepEqual([...linkedList], [12, 34]);
linkedList.addAll(1, [56, 78]);
assert.deepEqual([...linkedList], [12, 56, 78, 34]);
linkedList.clear();
assert.equal(linkedList.size(), 0);
linkedList.addAll([1, 2, 3, 4]);
assert.deepEqual([...linkedList], [1, 2, 3, 4]);
linkedList.addAll([5, 6]);
assert.deepEqual([...linkedList], [1, 2, 3, 4, 5, 6]);
linkedList.addAll(2, [7, 8]);
assert.deepEqual([...linkedList], [1, 2, 7, 8, 3, 4, 5, 6]);
});
it('addAllFirst', () => {
linkedList.add(0, 12);
linkedList.add(1, 34);
assert.deepEqual([...linkedList], [12, 34]);
linkedList.addAllFirst([56, 78]);
assert.deepEqual([...linkedList], [56, 78, 12, 34]);
});
it('addAllLast', () => {
linkedList.add(0, 12);
linkedList.add(1, 34);
assert.deepEqual([...linkedList], [12, 34]);
linkedList.addAllLast([56, 78]);
assert.deepEqual([...linkedList], [12, 34, 56, 78]);
});
it('pop', () => {
linkedList.add(0, 123);
linkedList.add(1, 456);
linkedList.add(2, 789);
linkedList.add(3, 111);
linkedList.add(4, 222);
assert.equal(linkedList.size(), 5);
assert.equal(linkedList.pop(-3), undefined);
assert.equal(linkedList.pop(-1), undefined);
assert.equal(linkedList.pop(6), undefined);
assert.equal(linkedList.pop(7), undefined);
assert.equal(linkedList.size(), 5);
assert.equal(linkedList.pop(0), 123);
assert.equal(linkedList.size(), 4);
assert.equal(linkedList.pop(0), 456);
assert.equal(linkedList.size(), 3);
assert.equal(linkedList.pop(1), 111);
assert.equal(linkedList.size(), 2);
assert.equal(linkedList.pop(1), 222);
assert.equal(linkedList.size(), 1);
assert.equal(linkedList.pop(0), 789);
assert.equal(linkedList.size(), 0);
assert.equal(linkedList.pop(0), undefined);
assert.equal(linkedList.size(), 0);
linkedList.addAll([1, 2, 3, 4]);
assert.equal(linkedList.pop(), 4);
assert.equal(linkedList.pop(), 3);
assert.equal(linkedList.pop(), 2);
assert.equal(linkedList.pop(), 1);
assert.equal(linkedList.pop(), undefined);
});
it('remove', () => {
linkedList.addAll([11, 22, 33, 11, 22, 33]);
assert.equal(linkedList.remove(22), true);
assert.equal(linkedList.removeFirst(11), true);
assert.equal(linkedList.remove(123), false);
assert.equal(linkedList.removeAt(), undefined);
assert.equal(linkedList.size(), 4);
assert.equal(linkedList.removeAt(1), 11);
assert.equal(linkedList.size(), 3);
assert.deepEqual([...linkedList], [33, 22, 33]);
linkedList.clear();
linkedList.addAll([11, 22, 33, 11, 22, 33]);
assert.equal(linkedList.removeLast(22), true);
assert.deepEqual([...linkedList], [11, 22, 33, 11, 33]);
assert.equal(linkedList.removeAt(2), 33);
assert.deepEqual([...linkedList], [11, 22, 11, 33]);
assert.equal(linkedList.removeAll(11), 2);
assert.deepEqual([...linkedList], [22, 33]);
});
it('removeMatch', () => {
linkedList.addAll([11, 22, 33, 11, 22, 33]);
assert.equal(linkedList.removeMatch(v => v === 22), 22);
assert.equal(linkedList.size(), 5);
assert.equal(linkedList.removeMatch(v => v % 2), 11);
assert.equal(linkedList.removeMatch(v => v % 2), 33);
assert.deepEqual([...linkedList], [11, 22, 33]);
linkedList.clear();
linkedList.addAll([11, 22, 33, 11, 22, 33]);
assert.equal(linkedList.removeMatchFirst(v => v % 2), 11);
assert.deepEqual([...linkedList], [22, 33, 11, 22, 33]);
assert.equal(linkedList.removeMatchLast(v => v === 22), 22);
assert.deepEqual([...linkedList], [22, 33, 11, 33]);
linkedList.clear();
linkedList.addAll([22, 33, 11, 22, 33]);
assert.deepEqual(linkedList.removeMatchAll(v => v % 2), [33, 11, 33]);
assert.deepEqual([...linkedList], [22, 22]);
});
it('clear', () => {
linkedList.addAllFirst([1, 2, 3, 4, 5]);
assert.equal(linkedList.size(), 5);
linkedList.clear();
assert.equal(linkedList.size(), 0);
});
it('set', () => {
linkedList.addLast(12);
linkedList.addLast(34);
linkedList.addLast(56);
linkedList.addLast(78);
assert.equal(linkedList.size(), 4);
assert.equal(linkedList.get(0), 12);
assert.equal(linkedList.set(0, 123), 12);
assert.equal(linkedList.get(0), 123);
assert.equal(linkedList.get(1), 34);
assert.equal(linkedList.set(1, 345), 34);
assert.equal(linkedList.get(1), 345);
assert.equal(linkedList.get(3), 78);
assert.equal(linkedList.set(3, 567), 78);
assert.equal(linkedList.get(3), 567);
assert.equal(linkedList.size(), 4);
assert.throws(() => linkedList.set(-1, 789), RangeError);
assert.throws(() => linkedList.set(5, 789), RangeError);
assert.throws(() => linkedList.set(6, 789), RangeError);
});
it('find', () => {
linkedList.addLast(12);
linkedList.addLast(34);
linkedList.addLast(56);
linkedList.addLast(78);
linkedList.addLast({ id: 123, name: 'hololo' });
linkedList.addLast({ id: 124, name: 'kakaka' });
linkedList.addLast({ id: 125, name: 'gugugu' });
assert.equal(linkedList.find(x => x === 34), 34);
assert.equal(linkedList.find(x => x % 50 === 6), 56);
assert.equal(linkedList.find(x => x.id === 124).name, 'kakaka');
assert.equal(linkedList.find(x => x.id === 126), undefined);
assert.equal(linkedList.find(x => x === 99), undefined);
});
it('isEmpty', () => {
assert.isTrue(linkedList.isEmpty());
linkedList.add(0, 3);
assert.isFalse(linkedList.isEmpty());
linkedList.pop(0);
assert.isTrue(linkedList.isEmpty());
linkedList.add(0, 123);
assert.isFalse(linkedList.isEmpty());
});
it('reversed', () => {
linkedList.addAllFirst([1, 2, 3, 4, 5]);
assert.deepEqual([...linkedList], [1, 2, 3, 4, 5]);
assert.deepEqual([...linkedList.reversed()], [5, 4, 3, 2, 1]);
});
});
describe('Iterator', () => {
let linkedList = null;
beforeEach(() => {
linkedList = new LinkedList();
});
it('Iterate without value', () => {
assert.deepEqual([...linkedList], []);
});
it('Iterate one value', () => {
linkedList.addLast(3);
assert.deepEqual([...linkedList], [3]);
});
it('Iterate some values', () => {
linkedList.addLast(3);
linkedList.addLast(6);
linkedList.addLast(9);
assert.deepEqual([...linkedList], [3, 6, 9]);
});
});
describe('Functional tools', () => {
it('forEach', () => {
const list = new LinkedList();
let acc = 0;
const accmulate = (x) => { acc += x; };
assert.equal(acc, 0);
list.forEach(accmulate);
assert.equal(acc, 0);
list.addAllFirst([11, 22, 33]);
list.forEach(accmulate);
assert.equal(acc, 66);
});
it('map', () => {
const list = new LinkedList();
assert.deepEqual([...list.map(x => x + 3)], []);
list.addAllFirst([11, 22, 33]);
assert.deepEqual([...list.map(x => x + 3)], [14, 25, 36]);
});
it('flatMap', () => {
const list = new LinkedList();
assert.deepEqual([...list.flatMap(x => [x, x + 3])], []);
list.addAllFirst([11, 22, 33]);
assert.deepEqual([...list.flatMap(x => [x, x + 3])], [11, 14, 22, 25, 33, 36]);
});
it('filter', () => {
const list = new LinkedList();
assert.deepEqual([...list.filter(x => x % 2)], []);
list.addAllFirst([1, 2, 3, 4, 5]);
assert.deepEqual([...list.filter(x => x % 2)], [1, 3, 5]);
assert.deepEqual([...list], [1, 2, 3, 4, 5]);
});
});
describe('Checking tools', () => {
it('some', () => {
assert.equal(new LinkedList().some(x => x > 5), false);
assert.equal(new LinkedList([1, 2, 3]).some(x => x > 5), false);
assert.equal(new LinkedList([4, 5, 6]).some(x => x > 5), true);
assert.equal(new LinkedList([7, 8, 9]).some(x => x > 5), true);
});
it('every', () => {
assert.equal(new LinkedList().every(x => x > 5), true);
assert.equal(new LinkedList([1, 2, 3]).every(x => x > 5), false);
assert.equal(new LinkedList([4, 5, 6]).every(x => x > 5), false);
assert.equal(new LinkedList([7, 8, 9]).every(x => x > 5), true);
});
it('includes', () => {
assert.equal(new LinkedList().includes(5), false);
assert.equal(new LinkedList([1, 2, 3]).includes(5), false);
assert.equal(new LinkedList([4, 5, 6]).includes(5), true);
assert.equal(new LinkedList([5]).includes(5), true);
});
});
});