diff --git a/__tests__/CircularDoublyLinkedList.test.js b/__tests__/CircularDoublyLinkedList.test.js index 0c9728d..b75d2d3 100644 --- a/__tests__/CircularDoublyLinkedList.test.js +++ b/__tests__/CircularDoublyLinkedList.test.js @@ -1,6 +1,6 @@ import test from 'tape'; -import { CircularDoublyLinkedList } from '../lib'; +import { CircularDoublyLinkedList, CircularSinglyLinkedList } from '../lib'; import { Node } from '../lib/Atomics'; const subject = 'The circular doubly linked list'; @@ -313,6 +313,16 @@ test(`${subject} is not modified when invoking 'moveAfter', 'moveBefore' with a t.end(); }); +test(`${subject} throws an error if provided a list of a different type`, t => { + const l = init(); + const l2 = new CircularSinglyLinkedList(); + + t.throws(() => l.pushBackList(l2)); + t.throws(() => l.pushFrontList(l2)); + + t.end(); +}); + /* refHelpers */ function checkListSize (list, expectedSize) { diff --git a/__tests__/CircularRingList.test.js b/__tests__/CircularRingList.test.js deleted file mode 100644 index fc971a2..0000000 --- a/__tests__/CircularRingList.test.js +++ /dev/null @@ -1,220 +0,0 @@ -// import test from 'tape'; - -// import { CircularRingList } from '../lib'; - -// const subject = 'The circular ring list'; -// const init = n => new CircularRingList(n); - - -// test(`${subject} maintains its integrity as a single-node list`, t => { -// const tryFail = (t => (...args) => { -// try { verify(...args); } -// catch (msg) { t.fail(msg); } -// })(t); - -// const r0 = init(); -// const r1 = init(1); - -// // base -// tryFail(r0, 0, 0); -// tryFail(r1, 1, 0); - -// t.end(); -// }); - -// function TestCornerCases() { - - -// // // insert -// // r1.link(r0); -// // tryFail(r0, 0, 0); -// // tryFail(r1, 1, 0); - -// // // insert -// // r1.link(r0); -// // tryFail(r0, 0, 0); -// // tryFail(r1, 1, 0); - -// // // unlink -// // r1.unlink(0); -// // tryFail(r1, 1, 0); -// } - -// // function makeN(n int) *Ring { -// // r = New(n) -// // for i = 1; i <= n; i++ { -// // r.Value = i -// // r = r.next() -// // } -// // return r -// // } - -// // function sumN(n int) int { return (n*n + n) / 2 } - -// // function TestNew(t *testing.T) { -// // for i = 0; i < 10; i++ { -// // r = New(i) -// // verify(r, i, -1) -// // } -// // for i = 0; i < 10; i++ { -// // r = makeN(i) -// // verify(r, i, sumN(i)) -// // } -// // } - -// // function Testlink1(t *testing.T) { -// // r1a = makeN(1) -// // var r1b Ring -// // r2a = r1a.link(&r1b) -// // verify(r2a, 2, 1) -// // if r2a != r1a { -// // throw `a) 2-element link failed`) -// // } - -// // r2b = r2a.link(r2a.next()) -// // verify(r2b, 2, 1) -// // if r2b != r2a.next() { -// // throw `b) 2-element link failed`) -// // } - -// // r1c = r2b.link(r2b) -// // verify(r1c, 1, 1) -// // verify(r2b, 1, 0) -// // } - -// // function Testlink2(t *testing.T) { -// // var r0 *Ring -// // r1a = &Ring{Value: 42} -// // r1b = &Ring{Value: 77} -// // r10 = makeN(10) - -// // r1a.link(r0) -// // verify(r1a, 1, 42) - -// // r1a.link(r1b) -// // verify(r1a, 2, 42+77) - -// // r10.link(r0) -// // verify(r10, 10, sumN(10)) - -// // r10.link(r1a) -// // verify(r10, 12, sumN(10)+42+77) -// // } - -// // function Testlink3(t *testing.T) { -// // var r Ring -// // n = 1 -// // for i = 1; i < 10; i++ { -// // n += i -// // verify(r.link(New(i)), n, -1) -// // } -// // } - -// // function Testunlink(t *testing.T) { -// // r10 = makeN(10) -// // s10 = r10.move(6) - -// // sum10 = sumN(10) - -// // verify(r10, 10, sum10) -// // verify(s10, 10, sum10) - -// // r0 = r10.unlink(0) -// // verify(r0, 0, 0) - -// // r1 = r10.unlink(1) -// // verify(r1, 1, 2) -// // verify(r10, 9, sum10-2) - -// // r9 = r10.unlink(9) -// // verify(r9, 9, sum10-2) -// // verify(r10, 9, sum10-2) - -// // } - -// // function Testlinkunlink(t *testing.T) { -// // for i = 1; i < 4; i++ { -// // ri = New(i) -// // for j = 0; j < i; j++ { -// // rj = ri.unlink(j) -// // verify(rj, j, -1) -// // verify(ri, i-j, -1) -// // ri.link(rj) -// // verify(ri, i, -1) -// // } -// // } -// // } - -// // // Test that calling Move() on an empty Ring initializes it. -// // function TestMoveEmptyRing(t *testing.T) { -// // var r Ring - -// // r.move(1) -// // verify(r, 1, 0) -// // } - - -// function dump (r) { -// if (r == null) return; - -// for (let i = 0, n = r.size(), p = r; i < n; p = p._next, i++) { -// console.log(i, p, p._prev, p._next); -// } -// } - -// function verify (r, n, sum) { -// // size -// let size = r.size(); - -// if (size != n) throw `r.size() == ${size}; expected ${n}`; - -// let i = 0; -// let v = 0; - -// r.each(function (p) { -// i++; - -// if (p != null) v += p; -// }); - -// if (i != n) throw `number of forward iterations == ${i}; expected ${n}`; - -// if (sum >= 0 && v != sum) throw `forward ring sum = ${v}; expected ${sum}`; - -// if (r.value == null) return; - -// // connections -// if (r._next != null) { -// let p; - -// for (let q = r; p == null || q != r; q = q._next) { -// if (p != null && p != q._prev) { -// throw `prev = ${p}, expected q.prev = ${q.prev}`; -// } -// p = q; -// } - -// if (p != r._prev) throw `prev = ${p}, expected r.prev = ${r.prev}`; -// } - -// // Next, Prev -// if (r.next() != r._next) throw `r.next() != r.next`; - -// if (r.prev() != r._prev) throw `r.Prev() != r.prev`; - -// // Move -// if (r.move(0) != r) throw `r.move(0) != r`; - -// if (r.move(n) != r) throw `r.move(${n}) != r`; - -// if (r.move(-n) != r) throw `r.move(${-n}) != r`; - -// for (let i = 0; i < 10; i++) { -// let ni = n + i; -// let mi = ni % n; - -// if (r.move(ni) != r.move(mi)) throw `r.move(${ni}) != r.move(${mi})`; - -// if (r.move(-ni) != r.move(-mi)) throw `r.move(${-ni}) != r.move(${-mi})`; -// } -// } diff --git a/__tests__/CircularSinglyLinkedList.test.js b/__tests__/CircularSinglyLinkedList.test.js index 0243f37..848358e 100644 --- a/__tests__/CircularSinglyLinkedList.test.js +++ b/__tests__/CircularSinglyLinkedList.test.js @@ -1,6 +1,6 @@ import test from 'tape'; -import { CircularSinglyLinkedList } from '../lib'; +import { CircularSinglyLinkedList, CircularDoublyLinkedList } from '../lib'; import { ForwardNode } from '../lib/Atomics'; const subject = 'The circular singly linked list'; @@ -433,6 +433,16 @@ test(`${subject} maintains integrity when operating upon a single-node list`, t t.end(); }); +test(`${subject} throws an error if provided a list of a different type`, t => { + const l = init(); + const l2 = new CircularDoublyLinkedList(); + + t.throws(() => l.pushBackList(l2)); + t.throws(() => l.pushFrontList(l2)); + + t.end(); +}); + /* Helpers */ function checkListSize (list, expectedSize) { diff --git a/lib/CircularDoublyLinkedList.js b/lib/CircularDoublyLinkedList.js index 3da88ad..84eb3cd 100644 --- a/lib/CircularDoublyLinkedList.js +++ b/lib/CircularDoublyLinkedList.js @@ -299,11 +299,12 @@ export class CircularDoublyLinkedList { * * The lists may be the same, but must not be null * @param {CircularDoublyLinkedList} other + * @throws {TypeError} Throws if provided a list that is not an instance of `CircularDoublyLinkedList` */ pushBackList (other) { if (!this.sentinel.next) { Object.assign(this, new CircularDoublyLinkedList()); - } + } else if (!(other instanceof CircularDoublyLinkedList)) throw new TypeError('other must be an instance of `CircularDoublyLinkedList`'); for (let i = other.size(), n = other.head(); i > 0; i--, n = other.next(n)) { this.insertValue(n.value, this.sentinel.prev); @@ -315,11 +316,12 @@ export class CircularDoublyLinkedList { * * The lists may be the same, but must not be null * @param {CircularDoublyLinkedList} other + * @throws {TypeError} Throws if provided a list that is not an instance of `CircularDoublyLinkedList` */ pushFrontList (other) { if (!this.sentinel.next) { Object.assign(this, new CircularDoublyLinkedList()); - } + } else if (!(other instanceof CircularDoublyLinkedList)) throw new TypeError('other must be an instance of `CircularDoublyLinkedList`'); for (let i = other.size(), n = other.tail(); i > 0; i--, n = other.prev(n)) { this.insertValue(n.value, this.sentinel); diff --git a/lib/CircularRingList.js b/lib/CircularRingList.js deleted file mode 100644 index abd3a8e..0000000 --- a/lib/CircularRingList.js +++ /dev/null @@ -1,96 +0,0 @@ -// export class CircularRingList { -// constructor (n) { -// if (n <= 0) return null; - -// this.next = this; -// this.prev = this; - -// for (let i = 0; i < n; i++) { -// this.next = this.init(); -// this.next.prev = this; -// } - -// this.next = this; -// this.prev = this; -// } - -// init () { -// this.next = this; -// this.prev = this; - -// return this; -// } - -// static next () { -// if (!this.next) return this.init(); -// return this.next; -// } - -// static prev () { -// if (!this.next) return this.init(); -// return this.prev; -// } - -// static move (n) { -// if (!this.next) return this.init(); - -// switch (n) { -// case n < 0: -// while (n < 0) { -// Object.assign(this, this.prev); -// n++; -// } -// break; -// case n > 0: -// while (n > 0) { -// Object.assign(this, this.next); -// n--; -// } -// break; -// } - -// return this; -// } - -// link (s) { -// const n = this.next(); - -// if (s != null) { -// const p = s.prev(); -// this.next = s; -// s.prev = this; -// n.prev = p; -// p.next = n; -// } - -// return n; -// } - -// unlink (n) { -// if (n <= 0) return null; -// return this.link(this.move(n + 1)); -// } - -// size () { -// let n = 0; - -// if (this != null) { -// n = 1; -// for (let p = this.next(); p != this; p = p.next) { -// n++; -// } -// } - -// return n; -// } - -// each (fn) { -// if (this != null) { -// fn(this.value); - -// for (let p = this.next(); p != this; p = p.next) { -// fn(p.value); -// } -// } -// } -// } diff --git a/lib/CircularSinglyLinkedList.js b/lib/CircularSinglyLinkedList.js index b9a405b..8b7e2ba 100644 --- a/lib/CircularSinglyLinkedList.js +++ b/lib/CircularSinglyLinkedList.js @@ -326,9 +326,11 @@ export class CircularSinglyLinkedList { * * The lists may be the same, but must not be null * @param {CircularSinglyLinkedList} other + * @throws {TypeError} Throws if provided a list that is not an instance of `CircularSinglyLinkedList` */ pushBackList (other) { if (!other) return; + if (!(other instanceof CircularSinglyLinkedList)) throw new TypeError('other must be an instance of `CircularSinglyLinkedList`'); for (let i = other.size(), n = other.head; i > 0; i--, n = other.next(n)) { this.pushBack(n.value); @@ -340,9 +342,11 @@ export class CircularSinglyLinkedList { * * The lists may be the same, but must not be null * @param {CircularSinglyLinkedList} other + * @throws {TypeError} Throws if provided a list that is not an instance of `CircularSinglyLinkedList` */ pushFrontList (other) { if (!other) return; + if (!(other instanceof CircularSinglyLinkedList)) throw new TypeError('other must be an instance of `CircularSinglyLinkedList`'); for (let i = other.size(), n = other.prev(other.head); i > 0; i--, n = other.prev(n)) { this.pushFront(n.value);