From cf8b0e15cba74a0fbedd96c0e7c4927b45c16d97 Mon Sep 17 00:00:00 2001 From: Kevin Hagerty Date: Thu, 10 Sep 2020 00:07:59 -0400 Subject: [PATCH] use the full test suite from codewars --- episode_58/class-list/src/index.test.js | 844 ++++++++++++++---------- 1 file changed, 487 insertions(+), 357 deletions(-) diff --git a/episode_58/class-list/src/index.test.js b/episode_58/class-list/src/index.test.js index 3fa2160..c504df8 100644 --- a/episode_58/class-list/src/index.test.js +++ b/episode_58/class-list/src/index.test.js @@ -1,362 +1,492 @@ -const List = require('./index'); - -const Test = { - describe, - it, - assertDeepEquals(val1, val2) { - expect(val1).toStrictEqual(val2); - }, -}; - -Test.describe('List', () => { - const plus = (v, w) => v + w; - const times = (v, w) => v * w; - const inc = (x) => x + 1; - const id = (x) => x; - const constant = id; - Test.it('Fibonci Sequence', () => { - Test.assertDeepEquals(List.FIB.take(8).toList(), [0, 1, 1, 2, 3, 5, 8, 13]); - Test.assertDeepEquals(List.FIB.take(8).drop(3).toList(), [2, 3, 5, 8, 13]); - Test.assertDeepEquals(List.FIB.take(79).toList(), [ - 0, - 1, - 1, - 2, - 3, - 5, - 8, - 13, - 21, - 34, - 55, - 89, - 144, - 233, - 377, - 610, - 987, - 1597, - 2584, - 4181, - 6765, - 10946, - 17711, - 28657, - 46368, - 75025, - 121393, - 196418, - 317811, - 514229, - 832040, - 1346269, - 2178309, - 3524578, - 5702887, - 9227465, - 14930352, - 24157817, - 39088169, - 63245986, - 102334155, - 165580141, - 267914296, - 433494437, - 701408733, - 1134903170, - 1836311903, - 2971215073, - 4807526976, - 7778742049, - 12586269025, - 20365011074, - 32951280099, - 53316291173, - 86267571272, - 139583862445, - 225851433717, - 365435296162, - 591286729879, - 956722026041, - 1548008755920, - 2504730781961, - 4052739537881, - 6557470319842, - 10610209857723, - 17167680177565, - 27777890035288, - 44945570212853, - 72723460248141, - 117669030460994, - 190392490709135, - 308061521170129, - 498454011879264, - 806515533049393, - 1304969544928657, - 2111485077978050, - 3416454622906707, - 5527939700884757, - 8944394323791464, - ]); - // List.FIB: an infinite list of Fibonacci (0,1) numbers ( [ 0, 1, 1, 2, 3, 5, 8, 13, .. ] ) - // You might use fib = 0 : 1 : zipWith (+) fib (tail fib). (Again, elegance over efficiency.) +Test.describe("List",()=>{ + const plus = (v,w) => v+w , times = (v,w) => v*w , inc = x => x+1 , id = x => x , constant = id; + Test.it("take, drop",()=>{ + const l = List.fromList([1,2,3,4]); + //console.log("l = [1,2,3,4]\n\nl.take(0)"); + Test.assertDeepEquals( l.take(0).toList(), [] ); + //console.log("l.take(3)"); + Test.assertDeepEquals( l.take(3).toList(), [1,2,3] ); + //console.log("l.take(-1)"); + Test.assertDeepEquals( l.take(-1).toList(), [] ); + //console.log("l.take(1e10)"); + Test.assertDeepEquals( l.take(1e10).toList(), [1,2,3,4] ); + //console.log("l.drop(0)"); + Test.assertDeepEquals( l.drop(0).toList(), [1,2,3,4] ); + //console.log("l.drop(3)"); + Test.assertDeepEquals( l.drop(3).toList(), [4] ); + //console.log("l.drop(-1)"); + Test.assertDeepEquals( l.drop(-1).toList(), [1,2,3,4] ); + //console.log("l.drop(1e10)"); + Test.assertDeepEquals( l.drop(1e10).toList(), [] ); + //console.log("l.take(0)"); + Test.assertDeepEquals( l.take(0).toList(), [] ); + //console.log("l.take(2)"); + Test.assertDeepEquals( l.take(2).toList(), [1,2] ); + //console.log("l.take(2)"); + Test.assertDeepEquals( l.take(2).toList(), [1,2] ); + //console.log("l.take(0)"); + Test.assertDeepEquals( l.take(0).toList(), [] ); + //console.log("l.drop(0)"); + Test.assertDeepEquals( l.drop(0).toList(), [1,2,3,4] ); + //console.log("l.drop(2)"); + Test.assertDeepEquals( l.drop(2).toList(), [3,4] ); + //console.log("l.drop(2)"); + Test.assertDeepEquals( l.drop(2).toList(), [3,4] ); + //console.log("l.drop(0)"); + Test.assertDeepEquals( l.drop(0).toList(), [1,2,3,4] ); + const taken = List.fromList([1,2,3,4]).take(2); + //console.log("l = [1,2,3,4].take(2)\n\nl"); + Test.assertDeepEquals( taken.toList(), [1,2] ); + //console.log("l"); + Test.assertDeepEquals( taken.toList(), [1,2] ); + const dropped = List.fromList([1,2,3,4]).drop(2); + //console.log("l = [1,2,3,4].drop(2)\n\nl"); + Test.assertDeepEquals( dropped.toList(), [3,4] ); + //console.log("l"); + Test.assertDeepEquals( dropped.toList(), [3,4] ); }); - Test.it('the basics', () => { - Test.assertDeepEquals(List.empty.toList(), []); - Test.assertDeepEquals(List.fromList([]).toList(), []); - Test.assertDeepEquals(List.fromList([1, 2, 3]).toList(), [1, 2, 3]); - Test.assertDeepEquals(List.fromList([1, 2, 3]).head(), 1); - Test.assertDeepEquals(List.fromList([]).head(), undefined); - Test.assertDeepEquals(List.fromList([1, 2, 3]).tail().toList(), [2, 3]); - Test.assertDeepEquals(List.fromList([]).tail().toList(), []); - Test.assertDeepEquals(List.fromList([1, 2, 3]).get(0), 1); - Test.assertDeepEquals(List.fromList([1, 2, 3]).get(1), 2); - Test.assertDeepEquals(List.fromList([1, 2, 3]).get(2), 3); - Test.assertDeepEquals(List.fromList([1, 2, 3, 4]).take(3).toList(), [ - 1, - 2, - 3, - ]); - Test.assertDeepEquals(List.fromList([1, 2, 3, 4]).drop(1).toList(), [ - 2, - 3, - 4, - ]); - Test.assertDeepEquals(List.empty.length(), 0); - Test.assertDeepEquals(List.fromList([1]).length(), 1); - Test.assertDeepEquals(List.fromList([1, 2]).length(), 2); - Test.assertDeepEquals(List.empty.nil(), true); - Test.assertDeepEquals(List.fromList([1]).nil(), false); - Test.assertDeepEquals(List.fromList([1, 2]).nil(), false); - Test.assertDeepEquals(List.fromList([2, 3]).cons(1).toList(), [1, 2, 3]); - Test.assertDeepEquals(List.empty.cons(1).toList(), [1]); - Test.assertDeepEquals(List.empty.append(List.empty).toList(), []); - Test.assertDeepEquals( - List.empty.append(List.fromList([1, 2, 3])).toList(), - [1, 2, 3], - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]).append(List.empty).toList(), - [1, 2, 3], - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .append(List.fromList([1, 2, 3])) - .toList(), - [1, 2, 3, 1, 2, 3], - ); - Test.assertDeepEquals(List.fromList([1, 2, 3]).slice(1).toList(), [2, 3]); - Test.assertDeepEquals(List.fromList([1, 2, 3]).slice(1, 2).toList(), [2]); - Test.assertDeepEquals(List.fromList([1, 2, 3]).slice().toList(), [1, 2, 3]); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .map((x) => x * x) - .toList(), - [1, 4, 9], - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .filter((x) => Boolean(x & 1)) - .toList(), - [1, 3], - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .filter((x) => !(x & 1)) - .toList(), - [2], - ); - Test.assertDeepEquals(List.fromList([1, 2, 3]).reverse().toList(), [ - 3, - 2, - 1, - ]); - Test.assertDeepEquals( - List.fromList([List.fromList([1, 2, 3]), List.fromList([1, 2, 3])]) - .concat() - .toList(), - [1, 2, 3, 1, 2, 3], - ); - Test.assertDeepEquals(List.empty.concat().toList(), []); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .zipWith(times, List.fromList([3, 2, 1])) - .toList(), - [3, 4, 3], - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]) - .foldr((x, z) => z.cons(x), List.empty) - .toList(), - [1, 2, 3], - ); - Test.assertDeepEquals( - List.empty.foldr(() => _ | _, Math.E), - Math.E, - ); - Test.assertDeepEquals(List.fromList([1, 2, 3]).foldl(plus, 0), 6); - Test.assertDeepEquals( - List.fromList([1, 2, 3]).foldl(inc, 0), - List.fromList([1, 2, 3]).length(), - ); - Test.assertDeepEquals(List.fromList([1, 2, 3]).scanr(plus, 0).toList(), [ - 6, - 5, - 3, - 0, - ]); - Test.assertDeepEquals(List.empty.scanr(times, 1).toList(), [1]); - Test.assertDeepEquals(List.fromList([1, 2, 3]).scanl(plus, 0).toList(), [ - 0, - 1, - 3, - 6, - ]); - Test.assertDeepEquals(List.empty.scanl(times, 1).toList(), [1]); - Test.assertDeepEquals(List.fromList([1, 2, 3]).elem(0), false); - Test.assertDeepEquals(List.fromList([1, 2, 3]).elem(2), true); - Test.assertDeepEquals(List.empty.elem(0), false); - Test.assertDeepEquals(List.fromList([1, 2, 3]).elemIndex(0), -1); - Test.assertDeepEquals(List.fromList([1, 2, 3]).elemIndex(2), 1); - Test.assertDeepEquals(List.empty.elemIndex(0), -1); - Test.assertDeepEquals( - List.fromList([1, 2, 3]).find((x) => !(x & 1)), - 2, - ); - Test.assertDeepEquals( - List.fromList([1, 3]).find((x) => !(x & 1)), - undefined, - ); - Test.assertDeepEquals( - List.empty.find((x) => !(x & 1)), - undefined, - ); - Test.assertDeepEquals( - List.fromList([1, 2, 3]).findIndex((x) => !(x & 1)), - 1, - ); - Test.assertDeepEquals( - List.fromList([1, 3]).find((x) => !(x & 1)), - undefined, - ); - Test.assertDeepEquals( - List.empty.find((x) => !(x & 1)), - undefined, - ); - Test.assertDeepEquals(List.fromList([true, false]).any(id), true); - Test.assertDeepEquals(List.empty.any(id), false); - Test.assertDeepEquals(List.fromList([true, false]).all(id), false); - Test.assertDeepEquals(List.empty.all(id), true); - Test.assertDeepEquals(List.fromList([1, 2, 3]).the(), undefined); - Test.assertDeepEquals(List.fromList([1, 1, 1]).the(), 1); - Test.assertDeepEquals(List.empty.the(), undefined); + Test.it("concat",()=>{ + //console.log("[[1,2,3]].concat()"); + Test.assertDeepEquals( List.fromList([ List.fromList([1,2,3]) ]).concat().toList(), [1,2,3] ); + //console.log("[[1,2,3],[1,2,3]].concat()"); + Test.assertDeepEquals( List.fromList([ List.fromList([1,2,3]), List.fromList([1,2,3]) ]).concat().toList(), [1,2,3,1,2,3] ); + //console.log("[[1,1],List.repeat(2)]].concat().take(3)"); + Test.assertDeepEquals( List.fromList([ List.fromList([1,1]), List.repeat(2) ]).concat().take(3).toList(), [1,1,2] ); + //console.log("List.repeat(List.repeat(1)).concat().take(3)"); + Test.assertDeepEquals( List.repeat(List.repeat(1)).concat().take(3).toList(), [1,1,1] ); + //console.log("List.iterate(inc,3).map(List.repeat).concat().take(3)"); + Test.assertDeepEquals( List.iterate(inc,3).map(List.repeat).concat().take(3).toList(), [3,3,3] ); + //console.log("List.repeat([1,2,3]).concat().take(4)"); + Test.assertDeepEquals( List.repeat(List.fromList([1,2,3])).concat().take(4).toList(), [1,2,3,1] ); }); - Test.it('list generators', () => { - Test.assertDeepEquals(List.repeat(1).take(10).toList(), [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - ]); - Test.assertDeepEquals(List.repeat(2).take(10).toList(), [ - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - ]); - Test.assertDeepEquals(List.repeat(3).take(10).toList(), [ - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - ]); - Test.assertDeepEquals( - List.iterate((x) => x + 1, 0) - .take(10) - .toList(), - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - ); - Test.assertDeepEquals( - List.cycle(List.fromList([1, 2, 3])) - .take(10) - .toList(), - [1, 2, 3, 1, 2, 3, 1, 2, 3, 1], - ); - Test.assertDeepEquals(List.replicate(10, 1).toList(), [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - ]); - Test.assertDeepEquals(List.replicate(10, 2).toList(), [ - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - ]); - Test.assertDeepEquals(List.replicate(10, 3).toList(), [ - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - ]); - Test.assertDeepEquals( - List.replicate(0, undefined).toList(), - List.empty.toList(), - ); - Test.assertDeepEquals( - List.replicate(10, 1).toList(), - List.iterate(id, 1).take(10).toList(), - ); + Test.it("empty",()=>{ + const empty = List.empty; + //console.log("l = List.empty\n\nl.concat()"); + Test.assertDeepEquals( empty.concat().toList(), [] ); + //console.log("l.nil()"); + Test.assertDeepEquals( empty.nil(), true ); + //console.log("l.any(x=>x===1)"); + Test.assertDeepEquals( empty.any( x => x===1 ), false ); + //console.log("l.all(Boolean)"); + Test.assertDeepEquals( empty.all(Boolean), true ); + //console.log("l.elem(0)"); + Test.assertDeepEquals( empty.elem(0), false ); + //console.log("l.elemIndex(0)"); + Test.assertDeepEquals( empty.elemIndex(0), -1 ); + //console.log("l.find(Boolean)"); + Test.assertDeepEquals( empty.find(Boolean), undefined ); + //console.log("l.findIndex(Boolean)"); + Test.assertDeepEquals( empty.findIndex(Boolean), -1 ); + //console.log("l.last()"); + Test.assertDeepEquals( empty.last(), undefined ); + //console.log("l.scanl(plus,0)"); + Test.assertDeepEquals( empty.scanl(plus,0).toList(), [0] ); + //console.log("l.scanr(plus,0)"); + Test.assertDeepEquals( empty.scanr(plus,0).toList(), [0] ); + //console.log("l.slice()"); + Test.assertDeepEquals( empty.slice().toList(), [] ); + //console.log("l.slice(3)"); + Test.assertDeepEquals( empty.slice(3).toList(), [] ); + //console.log("l.slice(3,6)"); + Test.assertDeepEquals( empty.slice(3,6).toList(), [] ); + //console.log("l.slice(3,2)"); + Test.assertDeepEquals( empty.slice(3,2).toList(), [] ); + //console.log("l.init()"); + Test.assertDeepEquals( empty.init().toList(), [] ); + //console.log("l.foldr(__=>_|_,0)"); + Test.assertDeepEquals( empty.foldr( __ => _|_ , 0 ), 0 ); + //console.log("l.foldr(constant,undefined)"); + Test.assertDeepEquals( empty.foldr(constant,undefined), empty.head() ); + //console.log("l.the()"); + Test.assertDeepEquals( empty.the(), undefined ); }); - - it('should not have side effects', () => { - const list = List.fromList([1, 2, 3, 4]).scanl(plus, 0); - expect(list.toList()) - .toStrictEqual([0, 1, 3, 6, 10]); - expect(list.take(3).toList()).toStrictEqual([0, 1, 3]); - expect(list.take(3).toList()).toStrictEqual([0, 1, 3]); + Test.it("scanl",()=>{ + const l = List.fromList([1,2,3,4]).scanl(plus,0); + //console.log("l = [1,2,3,4].scanl(plus,0)\n\nl"); + Test.assertDeepEquals( l.toList(), [0,1,3,6,10] ); + //console.log("l.take(0)"); + Test.assertDeepEquals( l.take(0).toList(), [] ); + //console.log("l.take(3)"); + Test.assertDeepEquals( l.take(3).toList(), [0,1,3] ); + //console.log("l.take(3)"); + Test.assertDeepEquals( l.take(3).toList(), [0,1,3] ); + }); + Test.it("scanr",()=>{ + const l = List.fromList([1,2,3,4]).scanr(plus,0); + //console.log("l = [1,2,3,4].scanr(plus,0)\n\nl"); + Test.assertDeepEquals( l.toList(), [10,9,7,4,0] ); + //console.log("l.take(0)"); + Test.assertDeepEquals( l.take(0).toList(), [] ); + //console.log("l.take(3)"); + Test.assertDeepEquals( l.take(3).toList(), [10,9,7] ); + //console.log("l.take(3)"); + Test.assertDeepEquals( l.take(3).toList(), [10,9,7] ); + Test.describe("Bonus points?",()=>{ + const VM = require("vm"), sandbox = VM.createContext({ List, inc, constant }); + try { + //console.log("List.repeat(1).scanr(constant,undefined).take(5)"); + VM.runInContext( "actual = List.repeat(1).scanr(constant,undefined).take(5).toList()", sandbox, { timeout: 10 } ); + Test.it("Bonus Points! :]",()=>{ + Test.assertDeepEquals( sandbox.actual, [1,1,1,1,1] ); + }); + } catch(e) { + Test.it( "No bonus points .. :/", () => Test.expect(true) ); + } + try { + //console.log("List.iterate(inc,0).scanr(inc,Infinity).take(5)"); + VM.runInContext( "actual = List.iterate(inc,0).scanr(inc,Infinity).take(5).toList()", sandbox, { timeout: 10 } ); + Test.it("Bonus Points! :]",()=>{ + Test.assertDeepEquals( sandbox.actual, [1,2,3,4,5] ); + }); + } catch(e) { + Test.it( "No bonus points .. :/", () => Test.expect(true) ); + } + try { + //console.log("List.repeat(0).scanr(constant(1),pi).take(5)"); + VM.runInContext( "actual = List.repeat(0).scanr( () => 1 , Math.PI ).take(5).toList()", sandbox, { timeout: 10 } ); + Test.it("Bonus Points! :]",()=>{ + Test.assertDeepEquals( sandbox.actual, [1,1,1,1,1] ); + }); + } catch(e) { + Test.it( "No bonus points .. :/", () => Test.expect(true) ); + } + }); + }); + Test.it("nil",()=>{ + //console.log("[].nil()"); + Test.assertDeepEquals( List.fromList([]).nil(), true ); + //console.log("List.empty.nil()"); + Test.assertDeepEquals( List.empty.nil(), true ); + //console.log("[1,2,3,4].nil()"); + Test.assertDeepEquals( List.fromList([1,2,3,4]).nil(), false ); + //console.log("[,1,2,3,4].nil()"); + Test.assertDeepEquals( List.fromList([,1,2,3,4]).nil(), false ); + //console.log("[1,2,3,4].filter( x => x<0 ).nil()"); + Test.assertDeepEquals( List.fromList([1,2,3,4]).filter( x => x<0 ).nil(), true ); + //console.log("[1,2,3,4].filter( x => x>0 ).nil()"); + Test.assertDeepEquals( List.fromList([1,2,3,4]).filter( x => x>0 ).nil(), false ); + }); + Test.it("zipWith",()=>{ + const l0 = List.iterate(inc,0), l1 = List.fromList([0,1,2,3,4,5,6,7,8,9]), l2 = l0.take(10); + //console.log("l0 = List.iterate(inc,0), l1 = [0,1,2,3,4,5,6,7,8,9], l2 = l0.take(10)\n\nl1 === l2"); + Test.assertDeepEquals( l1.toList(), l2.toList() ); + //console.log("l1 === l2"); + Test.assertDeepEquals( l1.toList(), l2.toList() ); + //console.log("l0.zipWith(times,l1)"); + Test.assertDeepEquals( l0.zipWith(times,l1).toList(), [0,1,4,9,16,25,36,49,64,81] ); + //console.log("l0.zipWith(times,l1)"); + Test.assertDeepEquals( l0.zipWith(times,l1).toList(), [0,1,4,9,16,25,36,49,64,81] ); + const l3 = l0.zipWith(times,l1); + //console.log("l3 = l0.zipWith(times,l1)\n\nl3"); + Test.assertDeepEquals( l3.toList(), [0,1,4,9,16,25,36,49,64,81] ); + //console.log("l3"); + Test.assertDeepEquals( l3.toList(), [0,1,4,9,16,25,36,49,64,81] ); + const l4 = l1.zipWith(times,l0); + //console.log("l4 = l1.zipWith(times,l0)\n\nl4"); + Test.assertDeepEquals( l4.toList(), [0,1,4,9,16,25,36,49,64,81] ); + //console.log("l4"); + Test.assertDeepEquals( l4.toList(), [0,1,4,9,16,25,36,49,64,81] ); + }); + Test.it("iterate",()=>{ + const l = List.iterate(inc,0).take(5); + //console.log("l = List.iterate(inc,0).take(5)\n\nl"); + Test.assertDeepEquals( l.toList(), [0,1,2,3,4] ); + //console.log("l"); + Test.assertDeepEquals( l.toList(), [0,1,2,3,4] ); + //console.log("l.the()"); + Test.assertDeepEquals( l.the(), undefined ); + //console.log("List.iterate(inc,0).take(1001).length()"); + Test.assertDeepEquals( List.iterate(inc,0).take(1001).length(), 1001 ); + //console.log("List.iterate(inc,0).take(1001).reverse().length()"); + Test.assertDeepEquals( List.iterate(inc,0).take(1001).reverse().length(), 1001 ); + //console.log("List.iterate(inc,0).findIndex( x => x>1000 )"); + Test.assertDeepEquals( List.iterate(inc,0).findIndex( x => x>1000 ), 1001 ); + //console.log("List.iterate(inc,1).take(1000).foldl(plus,0)"); + Test.assertDeepEquals( List.iterate(inc,1).take(1000).foldl(plus,0), 500500 ); + }); + Test.it("repeat",()=>{ + const l = List.repeat(3); + //console.log("l = List.repeat(3)\n\nl.take(5)"); + Test.assertDeepEquals( l.take(5).toList(), [3,3,3,3,3] ); + //console.log("l.take(4)"); + Test.assertDeepEquals( l.take(4).toList(), [3,3,3,3] ); + //console.log("l.take(5).the()"); + Test.assertDeepEquals( l.take(5).the(), 3 ); + //console.log("l.take(4).the()"); + Test.assertDeepEquals( l.take(4).the(), 3 ); + //console.log("l.take(999).length()"); + Test.assertDeepEquals( l.take(999).length(), 999 ); + }); + Test.it("replicate",()=>{ + const l = List.replicate(1000,1); + //console.log("l = List.replicate(1000,1)\n\nl.length()"); + Test.assertDeepEquals( l.length(), 1000 ); + //console.log("l.foldl(plus,0)"); + Test.assertDeepEquals( l.foldl(plus,0), 1000 ); + }); + Test.it("[1,2,1,3,4]",()=>{ + const l = List.fromList([1,2,1,3,4]) + //console.log("l = [1,2,1,3,4]\n\nl.scanl(plus,0)"); + Test.assertDeepEquals( l.scanl(plus,0).toList() , [0,1,3,4,7,11] ); + //console.log("l.reverse().scanr(plus,0)"); + Test.assertDeepEquals( l.reverse().scanr(plus,0).toList(), [11,7,4,3,1,0] ); + //console.log("l.last()"); + Test.assertDeepEquals( l.last(), 4 ); + //console.log("l.reverse()"); + Test.assertDeepEquals( l.reverse().toList(), [4,3,1,2,1] ); + //console.log("l.init()"); + Test.assertDeepEquals( l.init().toList(), [1,2,1,3] ); + //console.log("l.init()"); + Test.assertDeepEquals( l.init().toList(), [1,2,1,3] ); + //console.log("l.nil()"); + Test.assertDeepEquals( l.nil(), false ); + //console.log("l.reverse().nil()"); + Test.assertDeepEquals( l.reverse().nil(), false ); + //console.log("l.foldr(plus,0)"); + Test.assertDeepEquals( l.foldr(plus,0), 11 ); + //console.log("l.map(inc)"); + Test.assertDeepEquals( l.map(inc).toList(), [2,3,2,4,5] ); + //console.log("l.filter( x => x<3 )"); + Test.assertDeepEquals( l.filter( x => x<3 ).toList(), [1,2,1] ); + //console.log("l.filter( x => x<2 )"); + Test.assertDeepEquals( l.filter( x => x<2 ).toList(), [1,1] ); + //console.log("l.map(inc)"); + Test.assertDeepEquals( l.map(inc).toList(), [2,3,2,4,5] ); + //console.log("l.get(0)"); + Test.assertDeepEquals( l.get(0), 1 ); + //console.log("l.get(1)"); + Test.assertDeepEquals( l.get(1), 2 ); + //console.log("l.get(2)"); + Test.assertDeepEquals( l.get(2), 1 ); + //console.log("l.get(3)"); + Test.assertDeepEquals( l.get(3), 3 ); + //console.log("l.get(4)"); + Test.assertDeepEquals( l.get(4), 4 ); + //console.log("l.any( x => x===3 )"); + Test.assertDeepEquals( l.any( x => x===3 ), true ); + //console.log("l.any( x => x===6 )"); + Test.assertDeepEquals( l.any( x => x===6 ), false ); + //console.log("l.all( Boolean )"); + Test.assertDeepEquals( l.all( Boolean ), true ); + //console.log("l.all( x => x===3 )"); + Test.assertDeepEquals( l.all( x => x===3 ), false ); + //console.log("l.elem(4)"); + Test.assertDeepEquals( l.elem(4), true ); + //console.log("l.elem(6)"); + Test.assertDeepEquals( l.elem(6), false ); + //console.log("l.elemIndex(4)"); + Test.assertDeepEquals( l.elemIndex(4), 4 ); + //console.log("l.elemIndex(6)"); + Test.assertDeepEquals( l.elemIndex(6), -1 ); + //console.log("l.find( x => x>2 )"); + Test.assertDeepEquals( l.find( x => x>2 ), 3 ); + //console.log("l.findIndex( x => x>3 )"); + Test.assertDeepEquals( l.findIndex( x => x>3 ), 4 ); + //console.log("l.findIndex( x => x<0 )"); + Test.assertDeepEquals( l.findIndex( x => x<0 ), -1 ); + //console.log("l.slice()"); + Test.assertDeepEquals( l.slice().toList(), [1,2,1,3,4] ); + //console.log("l.slice(3)"); + Test.assertDeepEquals( l.slice(3).toList(), [3,4] ); + //console.log("l.slice(3,6)"); + Test.assertDeepEquals( l.slice(3,6).toList(), [3,4] ); + //console.log("l.slice(3,2)"); + Test.assertDeepEquals( l.slice(3,2).toList(), [] ); + //console.log("l.slice(2,3)"); + Test.assertDeepEquals( l.slice(2,3).toList(), [1] ); + //console.log("l.init()"); + Test.assertDeepEquals( l.init().toList(), [1,2,1,3] ); + //console.log("l.tail().slice()"); + Test.assertDeepEquals( l.tail().slice().toList(), [2,1,3,4] ); + //console.log("l.foldr(constant,undefined)"); + Test.assertDeepEquals( l.foldr(constant,undefined), l.head() ); + //console.log("l.foldr( (x,z) => z.cons(x) , List.empty ) === l"); + Test.assertDeepEquals( l.foldr( (x,z) => z.cons(x) , List.empty ).toList(), l.toList() ); + //console.log("l.the()"); + Test.assertDeepEquals( l.the(), undefined ); + const xs = l.init(); + //console.log("l' = l.init()\n\nl'"); + Test.assertDeepEquals( xs.toList(), [1,2,1,3] ); + //console.log("l'"); + Test.assertDeepEquals( xs.toList(), [1,2,1,3] ); + }); + Test.it("[[1,1,1],[2,2,2],[3,3,3]]",()=>{ + const l = List.fromList([ List.replicate(3,1), List.replicate(3,2), List.replicate(3,3) ]); + //console.log("l = [ List.replicate(3,1), List.replicate(3,2), List.replicate(3,3) ]\n\nl.concat()"); + Test.assertDeepEquals( l.concat().toList(), [1,1,1,2,2,2,3,3,3] ); + //console.log("l.map( v => v.toList() ).toList()"); + Test.assertDeepEquals( l.map( v => v.toList() ).toList(), [[1,1,1],[2,2,2],[3,3,3]] ); + //console.log("l.map( v => v.toList() ).toList()"); + Test.assertDeepEquals( l.map( v => v.toList() ).toList(), [[1,1,1],[2,2,2],[3,3,3]] ); + //console.log("l.map( v => v.all( x => x!==2 ) )"); + Test.assertDeepEquals( l.map( v => v.all( x => x!==2 ) ).toList(), [true,false,true] ); + //console.log("l.map( v => v.any( x => x!==2 ) )"); + Test.assertDeepEquals( l.map( v => v.any( x => x!==2 ) ).toList(), [true,false,true] ); + }); + Test.it("[[1,2,3],[1,2,3],[1,2,3]]",()=>{ + const l = List.replicate(3,List.fromList([1,2,3])); + //console.log("l = List.replicate(3,[1,2,3])\n\nl.map( v => v.all( x => x!==2 ) )"); + Test.assertDeepEquals( l.map( v => v.all( x => x!==2 ) ).toList(), [false,false,false] ); + //console.log("l.map( v => v.any( x => x!==2 ) )"); + Test.assertDeepEquals( l.map( v => v.any( x => x!==2 ) ).toList(), [true,true,true] ); + //console.log("l.concat()"); + Test.assertDeepEquals( l.concat().toList(), [1,2,3,1,2,3,1,2,3] ) + }); + Test.it("[1,2,3,1,2,3,1,2,3,..]",()=>{ + const endlessOneTwoThrees = List.cycle(List.fromList([1,2,3])); + //console.log("l = List.cycle([1,2,3])\n\nl.head()"); + Test.assertDeepEquals( endlessOneTwoThrees.head(), 1 ); + //console.log("l.tail().take(6)"); + Test.assertDeepEquals( endlessOneTwoThrees.tail().take(6).toList(), [2,3,1,2,3,1] ); + //console.log("l.filter(Boolean).take(6)"); + Test.assertDeepEquals( endlessOneTwoThrees.filter(Boolean).take(6).toList(), [1,2,3,1,2,3] ); + //console.log("l.map( x => x*x ).take(5)"); + Test.assertDeepEquals( endlessOneTwoThrees.map( x => x*x ).take(5).toList(), [1,4,9,1,4] ); + //console.log("l.map( x => x*x ).tail().findIndex( x => x===1 )"); + Test.assertDeepEquals( endlessOneTwoThrees.map( x => x*x ).tail().findIndex( x => x===1 ), 2 ); + }); + Test.it("[0,1,..]",()=>{ + const increasing = List.iterate(inc,0); + //console.log("l = List.iterate(inc,0)\n\nl.head()"); + Test.assertDeepEquals( increasing.head(), 0 ); + //console.log("l.tail().head()"); + Test.assertDeepEquals( increasing.tail().head(), 1 ); + //console.log("l.tail().take(3)"); + Test.assertDeepEquals( increasing.tail().take(3).toList(), [1,2,3] ); + //console.log("l.take(10)"); + Test.assertDeepEquals( increasing.take(10).toList(), [0,1,2,3,4,5,6,7,8,9] ); + //console.log("l.take(10)"); + Test.assertDeepEquals( increasing.take(10).toList(), [0,1,2,3,4,5,6,7,8,9] ); + //console.log("l.nil()"); + Test.assertDeepEquals( increasing.nil(), false ); + //console.log("l.foldr(constant)"); + Test.assertDeepEquals( increasing.foldr(constant), 0 ); + //console.log("l.foldr(constant(17))"); + Test.assertDeepEquals( increasing.foldr( () => 17 ), 17 ); + //console.log("l.scanl(plus,0).take(10)"); + Test.assertDeepEquals( increasing.scanl(plus,0).take(10).toList(), [0,0,1,3,6,10,15,21,28,36] ); + //console.log("l.take(10)"); + Test.assertDeepEquals( increasing.take(10).toList(), [0,1,2,3,4,5,6,7,8,9] ); + //console.log("l.drop(10).take(10)"); + Test.assertDeepEquals( increasing.drop(10).take(10).toList(), [10,11,12,13,14,15,16,17,18,19] ); + //console.log("l.zipWith(plus,l).take(10)"); + Test.assertDeepEquals( increasing.zipWith(plus,increasing).take(10).toList(), [0,2,4,6,8,10,12,14,16,18] ); + //console.log("l.init().take(10)"); + Test.assertDeepEquals( increasing.init().take(10).toList(), [0,1,2,3,4,5,6,7,8,9] ); + //console.log("l.get(9)"); + Test.assertDeepEquals( increasing.get(9), 9 ); + //console.log("l.get(0)"); + Test.assertDeepEquals( increasing.get(0), 0 ); + //console.log("l.get(8)"); + Test.assertDeepEquals( increasing.get(8), 8 ); + //console.log("l.get(3)"); + Test.assertDeepEquals( increasing.get(3), 3 ); + //console.log("l.get(6)"); + Test.assertDeepEquals( increasing.get(6), 6 ); + //console.log("l.get(4)"); + Test.assertDeepEquals( increasing.get(4), 4 ); + //console.log("l.get(5)"); + Test.assertDeepEquals( increasing.get(5), 5 ); + //console.log("l.get(1)"); + Test.assertDeepEquals( increasing.get(1), 1 ); + //console.log("l.get(2)"); + Test.assertDeepEquals( increasing.get(2), 2 ); + //console.log("l.get(7)"); + Test.assertDeepEquals( increasing.get(7), 7 ); + //console.log("l.any( x => x===3 )"); + Test.assertDeepEquals( increasing.any( x => x===3 ), true ); + //console.log("l.any( x => x===1000 )"); + Test.assertDeepEquals( increasing.any( x => x===1000 ), true ); + //console.log("l.any( x => x===6 )"); + Test.assertDeepEquals( increasing.any( x => x===6 ), true ); + //console.log("l.all(Boolean)"); + Test.assertDeepEquals( increasing.all(Boolean), false ); + //console.log("l.all( x => x===3 )"); + Test.assertDeepEquals( increasing.all( x => x===3 ), false ); + //console.log("l.elem(4)"); + Test.assertDeepEquals( increasing.elem(4), true ); + //console.log("l.elem(6)"); + Test.assertDeepEquals( increasing.elem(6), true ); + //console.log("l.elemIndex(4)"); + Test.assertDeepEquals( increasing.elemIndex(4), 4 ); + //console.log("l.elemIndex(6)"); + Test.assertDeepEquals( increasing.elemIndex(6), 6 ); + //console.log("l.find( x => x>2 )"); + Test.assertDeepEquals( increasing.find( x => x>2 ), 3 ); + //console.log("l.findIndex( x => x>3 )"); + Test.assertDeepEquals( increasing.findIndex( x => x>3 ), 4 ); + //console.log("l.slice().get(3)"); + Test.assertDeepEquals( increasing.slice().get(3), 3 ); + //console.log("l.slice().get(6)"); + Test.assertDeepEquals( increasing.slice().get(6), 6 ); + //console.log("l.slice().get(9)"); + Test.assertDeepEquals( increasing.slice().get(9), 9 ); + //console.log("l.slice().get(12)"); + Test.assertDeepEquals( increasing.slice().get(12), 12 ); + //console.log("l.slice(3).head()"); + Test.assertDeepEquals( increasing.slice(3).head(), 3 ); + //console.log("l.slice(3,6)"); + Test.assertDeepEquals( increasing.slice(3,6).toList(), [3,4,5] ); + //console.log("l.slice(3,2)"); + Test.assertDeepEquals( increasing.slice(3,2).toList(), [] ); + //console.log("l.slice(2,3)"); + Test.assertDeepEquals( increasing.slice(2,3).toList(), [2] ); + //console.log("l.slice(2e10,1e10)"); + Test.assertDeepEquals( increasing.slice(2e10,1e10).toList(), [] ); + //console.log("l.init().take(3)"); + Test.assertDeepEquals( increasing.init().take(3).toList(), [0,1,2] ); + //console.log("l.append(l).take(3)"); + Test.assertDeepEquals( increasing.append(increasing).take(3).toList(), [0,1,2] ); + //console.log("l.foldr(constant,undefined)"); + Test.assertDeepEquals( increasing.foldr(constant,undefined), increasing.head() ); + //console.log("l.foldr(constant(17),undefined)"); + Test.assertDeepEquals( increasing.foldr( () => 17 , undefined ), 17 ); + //console.log("l.the()"); + Test.assertDeepEquals( increasing.the(), undefined ); + }); + Test.it("the",()=>{ + //console.log("[].the()") + Test.assertDeepEquals( List.fromList([]).the(), undefined ); + //console.log("[0].the()") + Test.assertDeepEquals( List.fromList([0]).the(), 0 ); + //console.log("[1].the()") + Test.assertDeepEquals( List.fromList([1]).the(), 1 ); + //console.log("[0,0,0].the()") + Test.assertDeepEquals( List.fromList([0,0,0]).the(), 0 ); + //console.log("[1,1,1].the()") + Test.assertDeepEquals( List.fromList([1,1,1]).the(), 1 ); + //console.log("[0,1,2].the()") + Test.assertDeepEquals( List.fromList([0,1,2]).the(), undefined ); + //console.log("List.replicate(10,1).append(List.repeat(2)).the()") + Test.assertDeepEquals( List.replicate(10,1).append(List.repeat(2)).the(), undefined ); + }); + Test.it("pi",()=>{ + //console.log("List.PI.get(12)"); + Test.assertNotApproxEquals( List.PI.get(12), Math.PI ); + //console.log("List.PI.get(13)"); + Test.assertApproxEquals( List.PI.get(13), Math.PI ); + //console.log("List.PI.take(15)"); + const pi = [0, 3.333333333333333, 3.117283950617284, 3.1455761316872426, 3.1408505617610554, 3.1417411974336886, 3.141561587877591, 3.141599340966198, 3.141591184360906, 3.1415929813345667, 3.1415925796063506, 3.1415926704506854, 3.1415926497167876, 3.141592654485348, 3.141592653381539]; + for ( const v of List.PI.take(15).toList() ) + Test.assertApproxEquals( v, pi.shift() ); + }); + Test.it("primes",()=>{ + //console.log("List.PRIME.take(10)"); + Test.assertDeepEquals( List.PRIME.take(10).toList(), [2,3,5,7,11,13,17,19,23,29] ); + }); + Test.it("Fibonacci numbers",()=>{ + //console.log("List.FIB.take(12)"); + Test.assertDeepEquals( List.FIB.take(12).toList(), [0,1,1,2,3,5,8,13,21,34,55,89] ); + }); + Test.it("the obligatory random tests",()=>{ + for ( let i=20; i--; ) { + const length = Math.floor(Math.random()*10); + //console.log(`List.replicate(${length},${length})`); + Test.assertDeepEquals( List.replicate(length,length).toList(), Array.from( { length }, () => length ) ); + //console.log(`List.iterate( x => x-1 , ${length} ).take(${length})`); + Test.assertDeepEquals( List.iterate( x => x-1 , length ).take(length).toList(), Array.from( { length }, (_,i) => length-i ) ); + //console.log(`List.repeat(2).zipWith( times, List.cycle([1,2,3]) ).map( x => x-1 ).take(${length}).reverse()`); + Test.assertDeepEquals( List.repeat(2).zipWith( times, List.cycle( List.fromList([1,2,3]) ) ).map( x => x-1 ).take(length).reverse().toList(), Array.from( { length }, (_,i) => [1,3,5][i%3] ).reverse() ); + } }); }); - -// I think the one thing you were missing was memoization for filter/map/etc where there could be side effects - -// side effects: if you do x = list.filter(someCallback) and y=x.take(5) then print x and y, someCallback should only be evaluated once for the whole list - -// https://gist.github.com/docd27/fdc2b84a226f7eb982833fda27ab35dd \ No newline at end of file