From 244a4c42774617e240d6a3116cc20ecf476b7c82 Mon Sep 17 00:00:00 2001 From: Kamyar Nazeri Date: Tue, 26 May 2015 23:33:57 +0430 Subject: [PATCH] Add definitions for multiplexjs --- multiplexjs/multiplexjs-tests.ts | 2496 +++++++++++++++++++++++++++++ multiplexjs/multiplexjs.d.ts | 2551 ++++++++++++++++++++++++++++++ 2 files changed, 5047 insertions(+) create mode 100644 multiplexjs/multiplexjs-tests.ts create mode 100644 multiplexjs/multiplexjs.d.ts diff --git a/multiplexjs/multiplexjs-tests.ts b/multiplexjs/multiplexjs-tests.ts new file mode 100644 index 000000000..2b9d7e9e9 --- /dev/null +++ b/multiplexjs/multiplexjs-tests.ts @@ -0,0 +1,2496 @@ +/// +/// + + +module MxTests { + + "use strict"; + + import Enumerator = mx.Enumerator; + import Enumerable = mx.Enumerable; + import Comparer = mx.Comparer; + import EqualityComparer = mx.EqualityComparer; + import Collection = mx.Collection; + import List = mx.List; + import ReadOnlyCollection = mx.ReadOnlyCollection; + import Dictionary = mx.Dictionary; + import SortedList = mx.SortedList; + import HashSet = mx.HashSet; + import LinkedList = mx.LinkedList; + import Queue = mx.Queue; + import Stack = mx.Stack; + import Lookup = mx.Lookup; + import RuntimeComparer = mx.RuntimeComparer; + + + var Enumerator = mx.Enumerator, + Enumerable = mx.Enumerable, + Comparer = mx.Comparer, + EqualityComparer = mx.EqualityComparer, + Collection = mx.Collection, + List = mx.List, + ReadOnlyCollection = mx.ReadOnlyCollection, + KeyValuePair = mx.KeyValuePair, + Dictionary = mx.Dictionary, + SortedList = mx.SortedList, + HashSet = mx.HashSet, + LinkedList = mx.LinkedList, + LinkedListNode = mx.LinkedListNode, + Queue = mx.Queue, + Stack = mx.Stack; + + + + + + + /* Classes + ---------------------------------------------------------------------- */ + + interface SimpleObject { + name: string; + value: number; + } + + // class without equality-comparer + class SimpleClass { + }; + + + // class overriding '__hash__' and '__equals__' methods. + class SimpleClassWithComparer implements RuntimeComparer, SimpleObject { + + constructor(val: number) { + this.value = val; + this.name = val.toString(); + } + + public name: string; + public value: number; + + __hash__(): number { + return mx.hash(this.value, this.name); + } + + __equals__(obj: any) { + return obj instanceof SimpleClassWithComparer && obj.value === this.value && obj.name === this.name; + } + }; + + + + + + + /* Tests + ---------------------------------------------------------------------- */ + + module MultiplexTests { + + QUnit.module("Multiplex"); + + + QUnit.test("Multiplex Array", function (assert) { + + var _source = mx([1, 2, 3, 4]); + assert.ok(MxCount(_source) === 4, "Passed!"); + }); + + + QUnit.test("Multiplex String", function (assert) { + var _source = mx("Multiplex"); + assert.ok(MxCount(_source) === 9, "Passed!"); + }); + + + QUnit.test("Multiplex Object", function (assert) { + var _source = mx({ name: "mx", id: 1 }); + assert.ok(MxCount(_source) === 2, "Passed!"); + }); + + + QUnit.test("Multiplex Array-like", function (assert) { + var _source = mx(arguments); + assert.ok(MxCount(_source) === 1, "Passed!"); + }); + + + //QUnit.test("Multiplex Iterable", function (assert) { + // var _set = new Set(), + // _source = mx(_set); + + // _set.add(1); + // _set.add(2); + // _set.add(3); + // assert.ok(MxCount(_source) === 3, "Passed!"); + //}); + + + QUnit.test("Multiplex Custom Enumerator", function (assert) { + var _source = mx(>{ + getEnumerator: function (): Enumerator { + var count = 3, index = 0; + return { + current: undefined, + next: function () { + if (index++ < count) { + this.current = index; + return true; + } + else { + this.current = undefined; + return false; + } + } + }; + } + }); + assert.ok(MxCount(_source) === 3, "Passed!"); + }); + + + QUnit.test("Multiplex Generator", function (assert) { + try { + var _source = eval("mx(function* () { yield 1; yield 2; yield 3; })"); + assert.ok(MxCount(_source) === 3, "Passed!"); + } + catch (e) { assert.ok(true, "Generator not implemented by the browser"); } + }); + + + QUnit.test("Multiplex Legacy Generator", function (assert) { + var _source = mx(function () { + var count = 3, + index = 0; + + return new Enumerator(function (yielder) { + if (index++ < count) { + yielder(index); + } + }); + }); + assert.ok(MxCount(_source) === 3, "Passed!"); + }); + + + QUnit.test("mx.range", function (assert) { + var _source = mx.range(0, 4); + assert.deepEqual(_source.toArray(), [0, 1, 2, 3], "Passed!"); + }); + + + QUnit.test("mx.repeat", function (assert) { + var _source = mx.repeat(1, 4); + assert.deepEqual(_source.toArray(), [1, 1, 1, 1], "Passed!"); + }); + + + QUnit.test("mx.empty", function (assert) { + var _source = mx.empty(); + assert.ok(MxCount(_source) === 0, "Passed!"); + }); + + + QUnit.test("mx.is", function (assert) { + assert.ok(mx.is(mx.range(1, 10)), "Enumerable Passed!"); + assert.ok(mx.is([1]), "Array Passed!"); + assert.ok(mx.is("mx"), "String Passed!"); + //assert.ok(mx.is(new Set()), "Iterable Passed!"); + + assert.ok(mx.is({ + getEnumerator: function (): Enumerator { + var count = 3, index = 0; + return { + current: undefined, + next: function () { + if (index++ < count) { + this.current = index; + return true; + } + else { + this.current = undefined; + return false; + } + } + }; + } + }), "Custom Enumerator Passed!"); + + try { + assert.ok(mx.is(eval("mx(function* () { yield 1; yield 2; yield 3; })")), "Generator Passed!"); + } + catch (e) { assert.ok(true, "Generator not implemented by the browser"); } + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function MxCount(source: Enumerable): number { + var _e = source.getEnumerator(), + _i = 0; + + while (_e.next()) { + _i++; + } + + return _i; + } + } + + + module RuntimeTests { + + QUnit.module("Runtime"); + + + QUnit.test("hash", function (assert) { + + assert.ok(mx.hash(null) === 0, "hash null!"); + assert.ok(mx.hash(undefined) === 0, "hash undefined!"); + assert.ok(mx.hash(10) === mx.hash(10), "hash integer number!"); + assert.ok(mx.hash(10.5) === mx.hash(10.5), "hash float number!"); + assert.ok(mx.hash("string") === mx.hash("string"), "hash string!"); + assert.ok(mx.hash(true) === mx.hash(true), "hash boolean!"); + assert.ok(mx.hash(new Date(2015, 0, 1)) === mx.hash(new Date(2015, 0, 1)), "hash date!"); + assert.ok(mx.hash({ name: "A" }) === mx.hash({ name: "A" }), "hash object literal!"); + assert.ok(mx.hash(new SimpleClass()) !== mx.hash(new SimpleClass()), "hash class instance!"); + assert.ok(mx.hash(new SimpleClassWithComparer(10)) === mx.hash(new SimpleClassWithComparer(10)), "hash class instance overriding __hash__ method!"); + assert.ok(mx.hash(10, 10.5, "string", new Date(2015, 0, 1)) === mx.hash(10, 10.5, "string", new Date(2015, 0, 1)), "combine hash codes!"); + }); + + + QUnit.test("equals", function (assert) { + + assert.ok(mx.equals(null, null) === true, "equals null!"); + assert.ok(mx.equals(undefined, undefined) === true, "equals undefined!"); + assert.ok(mx.equals(10, 10), "equals integer number!"); + assert.ok(mx.equals(10.5, 10.5), "equals float number!"); + assert.ok(mx.equals("string", "string"), "equals string!"); + assert.ok(mx.equals(true, true), "equals boolean!"); + assert.ok(mx.equals(new Date(2015, 0, 1), new Date(2015, 0, 1)), "equals date!"); + assert.ok(mx.equals({ name: "A" }, { name: "A" }), "equals object literal!"); + assert.ok(mx.equals(new SimpleClass(), new SimpleClass()) === false, "equals class instance!"); + assert.ok(mx.equals(new SimpleClass(), new SimpleClass(), EqualityComparer.create((obj) => 0, (a, b) => true)), "equals class instance using comparer!"); + assert.ok(mx.equals(new SimpleClassWithComparer(10), new SimpleClassWithComparer(10)), "equals class instance overriding __equals__ method!"); + }); + + + QUnit.test("compare", function (assert) { + + assert.ok(mx.compare(1, null) === 1 && mx.compare(null, 1) === -1 && mx.compare(null, null) === 0, "compare null!"); + assert.ok(mx.compare(1, 0) === 1 && mx.compare(0, 1) === -1 && mx.compare(1, 1) === 0, "compare numbers!"); + assert.ok(mx.compare("B", "A") === 1 && mx.compare("A", "B") === -1 && mx.compare("A", "A") === 0, "compare string!"); + assert.ok(mx.compare(true, false) === 1 && mx.compare(false, true) === -1 && mx.compare(true, true) === 0, "compare bolean!"); + assert.ok(mx.compare(new Date(2015, 0, 2), new Date(2015, 0, 1)) === 1 && mx.compare(new Date(2015, 0, 1), new Date(2015, 0, 2)) === -1 && mx.compare(new Date(2015, 0, 1), new Date(2015, 0, 1)) === 0, "compare date!"); + assert.ok(mx.compare({ name: "A" }, { name: "B" }) === 0, "compare objects!"); + }); + + + QUnit.test("lambda", function (assert) { + + var _f1 = mx.runtime.lambda("t => t * t"), + _f2 = mx.runtime.lambda("(t, u) => t + u"), + _f3 = mx.runtime.lambda("(t, u, r) => t + u + r"), + _f4 = mx.runtime.lambda("(t, u) => {id:t, name:u}"); + + assert.ok(_f1(2) === 4, "square root lambda!"); + assert.ok(_f2(1, 2) === 3, "sum of 2 numbers lambda!"); + assert.ok(_f3(1, 2, 3) === 6, "sum of 3 numbers lambda!"); + assert.ok(_f4(1, "A").id === 1 && _f4(1, "A").name === "A", "object literal lambda!"); + }); + } + + + module LinqTests { + + QUnit.module("Linq"); + + + QUnit.test("aggregate", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).aggregate((a, b) => a + b) === 45, "Aggregate 10 numbers without seed!"); + assert.ok(mx(_arr).aggregate(10, (a, b) => a + b) === 55, "Aggregate 10 numbers with seed!"); + assert.ok(mx(_arr).aggregate(10, (a, b) => a + b, t => t * 2) === 110, "Aggregate 10 numbers with seed and result selector!"); + }); + + + QUnit.test("all", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).all(t => t < 100) === true, "First 10 numbers less than 100!"); + assert.ok(mx(_arr).all(t => t < 5) === false, "First 10 numbers less than 5!"); + }); + + + QUnit.test("any", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).any() === true, "First 10 numbers!"); + assert.ok(mx(_arr).any(t => t % 2 === 0) === true, "Any of the first 10 numbers is even!"); + assert.ok(mx(_arr).any(t => t > 10) === false, "Any of the first 10 numbers greater than 10!"); + }); + + + QUnit.test("average", function (assert) { + + assert.ok(mx(CreateNumberArray()).average() === 4.5, "Average of the first 10 numbers!"); + assert.throws(() => mx(CreateObjectLiteralArray()).average(), "throws an exception for average of non numeric values!"); + assert.throws(() => mx([]).average(), "throws an exception for average of empty collection!"); + }); + + + QUnit.test("concat", function (assert) { + var _s1 = [1, 2, 3], + _s2 = [3, 4], + _arr = CreateNumberArray(); + + assert.deepEqual(mx(_s1).concat(_s2).toArray(), [1, 2, 3, 3, 4], "Concat two array!"); + assert.ok(mx(_arr).concat(_arr).count() === 20, "Concat the first 10 numbers to itself!"); + }); + + + QUnit.test("contains", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateSimpleClassArray(), + _arr3 = CreateSimpleClassWithComparerArray(), + _arr4 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).contains(1) === true, "1 contains in the first 10 numbers!"); + assert.ok(mx(_arr1).contains(10) === false, "10 does not contains in the first 10 numbers!"); + + assert.ok(mx(_arr2).contains(new SimpleClass()) === false, "Class instance without equality-comparer!"); + assert.ok(mx(_arr2).contains(new SimpleClass(), { hash: () => 0, equals: () => true }) === true, "Class instance with equality-comparer!"); + + assert.ok(mx(_arr3).contains(new SimpleClassWithComparer(5)) === true, "Class instance overriding equality-comparer!"); + + assert.ok(mx(_arr4).contains({ name: "n5", inner: { index: 5, val: {} } }) === true, "Object literal without equality-comparer!"); + assert.ok(mx(_arr4).contains({ name: "n5", inner: null }, { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }) === true, "Object literal with equality-comparer!"); + }); + + + QUnit.test("count", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).count() === 10, "Count of the first 10 numbers!"); + assert.ok(mx(_arr).count(t => t % 2 === 0) === 5, "Count of the first even 10 numbers!"); + }); + + + QUnit.test("defaultIfEmpty", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx([]).defaultIfEmpty(1).toArray(), [1], "Empty array devalut value!"); + assert.ok(mx(_arr).defaultIfEmpty(1).count() === 10, "Count of the first 10 numbers with defaultIfEmpty!"); + assert.ok(mx(_arr).where(t => t > 100).defaultIfEmpty(10).count() === 1, "Count of the first 10 numbers greater than 100 with defaultIfEmpty!"); + }); + + + QUnit.test("distinct", function (assert) { + + var _arr1 = CreateObjectLiteralArray(), + _arr2 = CreateComplexObjectLiteralArray(), + _arr3 = CreateNumberArray(), + _arr4 = CreateFloatNumberArray(), + _arr5 = CreateStringArray(), + _arr6 = CreateDateArray(), + _arr7 = CreateBooleanArray(), + _arr8 = CreateSimpleClassWithComparerArray(), + _arr9 = CreateSimpleClassArray(); + + assert.ok(mx(_arr1).distinct().count() === 1, "Array of 10 empty object literal!"); + assert.ok(mx(_arr2).distinct().count() === 10, "Array of 10 distinct complex object literal!"); + assert.ok(mx(_arr3).distinct().count() === 10, "Array of 10 distinct numbers!"); + assert.ok(mx(_arr4).distinct().count() === 10, "Array of 10 distinct float numbers!"); + assert.ok(mx(_arr5).distinct().count() === 10, "Array of 10 distinct strings!"); + assert.ok(mx(_arr6).distinct().count() === 10, "Array of 10 distinct date objects!"); + assert.ok(mx(_arr7).distinct().count() === 2, "Array of 10 boolean values!"); + assert.ok(mx(_arr8).distinct().count() === 10, "Array of 10 distinct class instances overriding equality-comparer!"); + assert.ok(mx(_arr9).distinct().count() === 10, "Array of 10 distinct class instances!"); + assert.ok(mx(_arr2).distinct({ + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).count() === 10, "Array of 10 distinct complex object literal with equality-comparer!"); + }); + + + QUnit.test("except", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateObjectLiteralArray(), + _arr3 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).except(CreateNumberArray()).count() === 0, "Array of first 10 numbers except first 10 numbers!"); + assert.deepEqual(mx(_arr1).except([0, 1, 2, 3, 4]).toArray(), [5, 6, 7, 8, 9], "Array of first 10 numbers except first 5 numbers!"); + assert.ok(mx(_arr2).except([{}]).count() === 0, "Array of 10 empty object literal except an empty object literal!"); + assert.ok(mx(_arr3).except([{ name: "n5", inner: null }]).count() === 10, "Array of 10 distinct complex object literal without equality-comparer!"); + assert.ok(mx(_arr3).except([{ name: "n5", inner: null }], { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).count() === 9, "Array of 10 distinct complex object literal with equality-comparer!"); + }); + + + QUnit.test("elementAt", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).elementAt(0) === 0, "First element of the first 10 numbers!"); + assert.throws(() => mx(_arr).elementAt(100), "throws an exception for 100th element of the first 10 numbers!"); + }); + + + QUnit.test("first", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).first() === 0, "First element of the first 10 numbers!"); + assert.ok(mx(_arr).first(t => t > 5) === 6, "First element greater than 5 of the first 10 numbers!"); + assert.throws(() => mx([]).first(), "throws an exception getting first element of an empty collection!"); + assert.throws(() => mx(_arr).first(t => t > 100), "throws an exception getting first element greater than 100 of the first 10 numbers!"); + }); + + + QUnit.test("firstOrDefault", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).firstOrDefault() === 0, "First element of the first 10 numbers or default!"); + assert.ok(mx(_arr).firstOrDefault(t => t > 5) === 6, "First element greater than 5 of the first 10 numbers or default!"); + assert.ok(mx(_arr).firstOrDefault(t => t > 100) === null, "First element greater than 100 of the first 10 numbers or default!"); + assert.ok(mx(_arr).firstOrDefault(t => t > 100, 100) === 100, "First element greater than 100 of the first 10 numbers or 100 as default!"); + }); + + + QUnit.test("forEach", function (assert) { + + var _arr = CreateNumberArray(), + _sum = 0; + + mx(_arr).forEach(t => _sum += t); + assert.ok(_sum === 45, "ForEach operation on the first 10 numbers!"); + }); + + + QUnit.test("groupBy", function (assert) { + + var _arr1 = CreateObjectLiteralArray(), + _arr2 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).groupBy(t => t).count() === 1, "Group 10 distinct empty object literals!"); + assert.ok(mx(_arr2).groupBy(t => t.name).count() === 10, "Group 10 distinct complex object literals by name!"); + assert.ok(mx(_arr2).groupBy(t => t.name).first().key === "n0", "Group 10 distinct complex object literals by name, retrieve first key!"); + assert.ok(mx(_arr2).groupBy(t => t.name).first().count() === 1, "Group 10 distinct complex object literals by name, retrieve first group count!"); + }); + + + QUnit.test("groupJoin", function (assert) { + + var _arr1 = [{ name: "A", val: 1 }, { name: "B", val: 2 }, { name: "C", val: 3 }, { name: "D", val: 4 }], + _arr2 = [{ code: "A" }, { code: "A" }, { code: "B" }, { code: "B" }, { code: "C" }], + _result = mx(_arr1).groupJoin(_arr2, t => t.name, u => u.code, (t, u) => ({ item: t, group: u })); + + assert.ok(_result.count() === 4, "groupJoin 2 complex-object array, getting count"); + assert.ok(_result.first().item.name === "A", "groupJoin 2 complex-object array, getting item"); + assert.ok(_result.first().group.count() === 2, "groupJoin 2 complex-object array, getting group count"); + assert.ok(_result.last().group.count() === 0, "groupJoin 2 complex-object array, getting empty group count"); + }); + + + QUnit.test("intersect", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateObjectLiteralArray(), + _arr3 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).intersect(CreateNumberArray()).count() === 10, "Array of first 10 numbers intersect with first 10 numbers!"); + assert.deepEqual(mx(_arr1).intersect([2, 3, 4]).toArray(), [2, 3, 4], "Array of first 10 numbers intersect with 3 numbers!"); + assert.ok(mx(_arr2).intersect([{}]).count() === 10, "Array of 10 empty object literal intersect with an empty object literal!"); + assert.ok(mx(_arr3).intersect([{ name: "n5", inner: null }]).count() === 0, "Array of 10 distinct complex object literal without equality-comparer!"); + assert.ok(mx(_arr3).intersect([{ name: "n5", inner: null }], { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).count() === 1, "Array of 10 distinct complex object literal with equality-comparer!"); + }); + + + QUnit.test("join", function (assert) { + var _arr1 = [{ name: "A", val: 1 }, { name: "B", val: 2 }, { name: "C", val: 3 }, { name: "D", val: 4 }], + _arr2 = [{ code: "A" }, { code: "A" }, { code: "B" }, { code: "B" }, { code: "C" }], + _arr3 = CreateObjectLiteralArray(), + _result = mx(_arr1).join(_arr2, t => t.name, u => u.code, (t, u) => ({ item1: t, item2: u })); + + assert.ok(_result.count() === 5, "join 2 complex-object array, getting count"); + assert.ok(_result.first().item1.name === "A" && _result.first().item2.code === "A", "join 2 complex-object array, getting item"); + assert.ok(mx(_arr3).join(mx(CreateObjectLiteralArray()), t => t, u => u, (t, u) => t).count() === 100, "join 2 empty object-literal array"); + assert.ok(mx(mx.empty()).join(mx(_arr3), t => t, u => u, (t, u) => t).count() === 0, "join empty collection with an array"); + }); + + + QUnit.test("last", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).last() === 9, "Last element of the first 10 numbers!"); + assert.ok(mx(_arr).last(t => t < 5) === 4, "Last element less than 5 of the first 10 numbers!"); + assert.throws(() => mx([]).last(), "throws an exception getting last element of an empty collection!"); + assert.throws(() => mx(_arr).last(t => t > 100), "throws an exception getting first element greater than 100 of the first 10 numbers!"); + }); + + + QUnit.test("lastOrDefault", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).lastOrDefault() === 9, "Last element of the first 10 numbers or default!"); + assert.ok(mx(_arr).lastOrDefault(t => t < 5) === 4, "Last element greater than 5 of the first 10 numbers or default!"); + assert.ok(mx(_arr).lastOrDefault(t => t > 100) === null, "Last element greater than 100 of the first 10 numbers or default!"); + assert.ok(mx(_arr).lastOrDefault(t => t > 100, 100) === 100, "Last element greater than 100 of the first 10 numbers or 100 as default!"); + }); + + + QUnit.test("max", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateStringArray(), + _arr3 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).max() === 9, "Maximum of the first 10 numbers!"); + assert.ok(mx(_arr2).max() === "9_string", "Maximum of the 10 string array!"); + assert.ok(mx(_arr3).max(t => t.name) === "n9", "Maximum of a complex array by selector!"); + assert.throws(() => mx([]).max(), "throws an exception getting maximum of an empty collection!"); + }); + + + QUnit.test("min", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateStringArray(), + _arr3 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).min() === 0, "Minimum of the first 10 numbers!"); + assert.ok(mx(_arr2).min() === "0_string", "Minimum of the 10 string array!"); + assert.ok(mx(_arr3).min(t => t.name) === "n0", "Minimum of a complex array by selector!"); + assert.throws(() => mx([]).min(), "throws an exception getting minimum of an empty collection!"); + }); + + + QUnit.test("ofType", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).ofType(Number).count() === 10, "Cast array of numbers to number!"); + assert.ok(mx(_arr).ofType(String).count() === 0, "Cast array of numbers to string!"); + }); + + + QUnit.test("orderBy", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateComplexObjectLiteralArray(), + _arr3 = [{ name: "a", val: 1 }, { name: "a", val: 2 }, { name: "b", val: 1 }, { name: "c", val: 2 }], + _result = [{ name: "a", val: 1 }, { name: "b", val: 1 }, { name: "a", val: 2 }, { name: "c", val: 2 }] + + assert.deepEqual(mx(_arr1).orderBy(t => t).take(5).toArray(), [0, 1, 2, 3, 4], "Order array of numbers ascending!"); + assert.ok(mx(_arr2).orderBy(t => t.name).thenByDescending(t => t.inner.index).first().name === "n0", "Order array of complex object by 'name' ascending then by 'inner.index' descending !"); + assert.deepEqual(mx(_arr3).orderBy(t => t.val).thenBy(t => t.name).toArray(), _result, "Order and thenBy!"); + assert.ok(mx(_arr2).orderBy(t => t.name, { + hash: o => mx.hash(o), + equals: (a, b) => a === b + }).first().name === "n0", "Order array of complex object ascending with comparer!"); + }); + + + QUnit.test("orderByDescending", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateComplexObjectLiteralArray(), + _arr3 = [{ name: "a", val: 1 }, { name: "a", val: 2 }, { name: "b", val: 1 }, { name: "c", val: 2 }], + _result = [{ name: "a", val: 2 }, { name: "c", val: 2 }, { name: "a", val: 1 }, { name: "b", val: 1 }]; + + assert.deepEqual(mx(_arr1).orderByDescending(t => t).take(5).toArray(), [9, 8, 7, 6, 5], "Order array of numbers descending!"); + assert.ok(mx(_arr2).orderByDescending(t => t.name).thenByDescending(t => t.inner.index).first().name === "n9", "Order array of complex object by 'name' descending then by 'inner.index' descending !"); + assert.deepEqual(mx(_arr3).orderByDescending(t => t.val).thenBy(t => t.name).toArray(), _result, "Order descending and thenBy!"); + assert.ok(mx(_arr2).orderByDescending(t => t.name, { + hash: o => mx.hash(o), + equals: (a, b) => a === b + }).first().name === "n9", "Order array of complex object descending with comparer!"); + }); + + + QUnit.test("reverse", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateStringArray(); + + assert.deepEqual(mx(_arr1).reverse().take(5).toArray(), [9, 8, 7, 6, 5], "Reverse array of first 10 numbers!"); + assert.ok(mx(_arr2).reverse().first() === "9_string", "Reverse array of strings!"); + }); + + + QUnit.test("sequenceEqual", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).sequenceEqual(mx(CreateNumberArray())), "sequenceEqual on array of numbers!"); + assert.ok(mx([1, 2, 3]).sequenceEqual(mx([1, 2])) === false, "sequenceEqual on inharmonic arrays of numbers!"); + assert.ok(mx([{ name: "a" }]).sequenceEqual(mx([{ name: "a", val: 1 }]), { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }), "sequenceEqual on arrays of objects with comparer!"); + }); + + + QUnit.test("select", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).select(t => t + 100).first() === 100, "select first 10 numbers plus 100!"); + assert.ok(mx(_arr).select((t, i) => i).last() === 9, "select index while enumerating 10 numbers!"); + }); + + + QUnit.test("selectMany", function (assert) { + + var _arr = [{ name: "A", values: [1, 2, 3, 4] }, { name: "B", values: [5, 6, 7, 8] }]; + + assert.ok(mx(_arr).selectMany(t => t.values).count() === 8, "selectMany on complex objects!"); + assert.deepEqual(mx(_arr).selectMany(t => t.values, (t, u) => ({ name: t.name, value: u })).first(), { name: "A", value: 1 }, "selectMany on complex objects with result selector!"); + }); + + + QUnit.test("single", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx([1]).single() === 1, "Single element of a single array!"); + assert.ok(mx(_arr).single(t => t === 1) === 1, "Single element equal to 1 of the first 10 numbers!"); + assert.throws(() => mx([]).single(), "throws an exception getting single element of an empty collection!"); + assert.throws(() => mx(_arr).single(), "throws an exception getting single element of an collection containing more than one element!"); + assert.throws(() => mx(_arr).single(t => t > 100), "throws an exception getting single element greater than 100 of the first 10 numbers!"); + assert.throws(() => mx(_arr).single(t => t < 10), "throws an exception getting single element less than 10 of the first 10 numbers!"); + }); + + + QUnit.test("singleOrDefault", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx([1]).singleOrDefault() === 1, "Single element of a single array or default!"); + assert.ok(mx([]).singleOrDefault() === null, "Single element of an empty array or default!"); + assert.ok(mx(_arr).singleOrDefault(t => t === 1) === 1, "Single element equal to 1 of the first 10 numbers or default!"); + assert.ok(mx(_arr).singleOrDefault(t => t === 100, 100) === 100, "Single element of an empty array or default!"); + assert.throws(() => mx(_arr).singleOrDefault(), "throws an exception getting single element of an collection containing more than one element!"); + assert.throws(() => mx(_arr).singleOrDefault(t => t < 10), "throws an exception getting single element less than 10 of the first 10 numbers!"); + }); + + + QUnit.test("skip", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx(_arr).skip(5).toArray(), [5, 6, 7, 8, 9], "Skip 5 element of a the first 10 numbers!"); + assert.deepEqual(mx(_arr).where(t => t % 2 === 0).skip(3).toArray(), [6, 8], "Skip 3 element of a the first 10 even numbers!"); + assert.ok(mx(_arr).skip(0).count() === 10, "Skip no items!"); + assert.ok(mx(_arr).skip(100).count() === 0, "Skip more than count of the collection!"); + }); + + + QUnit.test("skipWhile", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx(_arr).skipWhile(t => t < 5).toArray(), [5, 6, 7, 8, 9], "Skip while elements are less than 5 from the first 10 even numbers!"); + assert.ok(mx(_arr).skipWhile(t => t > 5).count() === 10, "Skip while elements are greater than 5 from the first 10 even numbers!"); + }); + + + QUnit.test("sum", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).sum() === 45, "Sum of the first 10 numbers!"); + assert.ok(mx(_arr).sum(t => t * 2) === 90, "Sum of the first 10 numbers multiply by 2!"); + assert.throws(() => mx(CreateObjectLiteralArray()).sum(), "throws an exception getting sum of non numeric elements!"); + assert.throws(() => mx(CreateComplexObjectLiteralArray()).sum(t => t.name), "throws an exception getting sum of non numeric properties!"); + }); + + + QUnit.test("take", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx(_arr).take(5).toArray(), [0, 1, 2, 3, 4], "Take 5 element of a the first 10 numbers!"); + assert.deepEqual(mx(_arr).where(t => t % 2 === 0).take(3).toArray(), [0, 2, 4], "Take 3 element of a the first 10 even numbers!"); + assert.ok(mx(_arr).take(0).count() === 0, "Take no items!"); + assert.ok(mx(_arr).take(100).count() === 10, "Take more than count of the collection!"); + }); + + + QUnit.test("takeWhile", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx(_arr).takeWhile(t => t < 5).toArray(), [0, 1, 2, 3, 4], "Take while elements are less than 5 from the first 10 even numbers!"); + assert.ok(mx(_arr).takeWhile(t => t > 5).count() === 0, "Take while elements are greater than 5 from the first 10 even numbers!"); + }); + + + QUnit.test("toArray", function (assert) { + + var _arr = CreateNumberArray(); + + assert.deepEqual(mx(_arr).where(t => t < 5).toArray(), [0, 1, 2, 3, 4], "Elements less than 5 from the first 10 even numbers!"); + }); + + + QUnit.test("toDictionary", function (assert) { + + var _arr = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr).toDictionary(t => t.name).count() === 10, "toDictionary key-selector!"); + assert.ok(mx(_arr).toDictionary(t => t.name, t => t.inner.index).first().value === 0, "toDictionary key-selector & element-selector!"); + assert.ok(mx(_arr).toDictionary(t => t, { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).first().key.name === "n0", "toDictionary key-selector & comparer!"); + + assert.ok(mx(_arr).toDictionary(t => t, t => t.inner.index, { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).first().value === 0, "toDictionary key-selector, element-selector & comparer!"); + + assert.throws(() => mx([1, 1, 2]).toDictionary(t => t), "throws an exception with duplicate keys!"); + }); + + + QUnit.test("toList", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).toList().count() === 10, "toList first 10 numbers!"); + assert.ok(mx(_arr).toList()[1] === 1, "toList indexer first 10 numbers!"); + }); + + + QUnit.test("toLookup", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).toLookup(t => t).count() === 10, "toLookup first 10 numbers!"); + assert.ok(mx(_arr1).toLookup(t => t).get(1).count() === 1, "toLookup indexer first 10 numbers!"); + + assert.ok(mx(_arr2).toLookup(t => t, { + hash: o => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).first().first().name === "n0", "toLookup with key-selector and comparer!"); + + assert.ok(mx(_arr2).toLookup(t => t, t => t.name, { + hash: (o) => mx.hash(o.name), + equals: (a, b) => a.name === b.name + }).first().first() === "n0", "toLookup with key-selector, element-selector and comparer!"); + }); + + + QUnit.test("union", function (assert) { + + var _arr = CreateNumberArray(); + + assert.ok(mx(_arr).union(CreateNumberArray()).count() === 10, "Union first 10 numbers with itself!"); + assert.deepEqual(mx([1, 2]).union(mx([2, 3])).toArray(), [1, 2, 3], "Union two arrays!"); + }); + + + QUnit.test("where", function (assert) { + + var _arr1 = CreateNumberArray(), + _arr2 = CreateComplexObjectLiteralArray(); + + assert.ok(mx(_arr1).where(t => t < 5).count() === 5, "Filter first 10 numbers less than 10!"); + assert.ok(mx(_arr2).where(t => t.inner.index < 5).count() === 5, "Filter complex object by value!"); + assert.deepEqual(mx(_arr1).where(t => t <= 1).toArray(), [0, 1], "Deep equal check!"); + }); + + + QUnit.test("zip", function (assert) { + + assert.ok(mx([1, 2]).zip([3, 4], (t, u) => t + u).first() === 4, "Zip two numeric array!"); + assert.ok(mx([1, 2]).zip([3], (t, u) => t + u).count() === 1, "Zip two inharmonic numeric array!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateObjectLiteralArray(): Object[] { + return mx.range(0, 10).select(t => ({})).toArray(); + } + + function CreateComplexObjectLiteralArray(): { name: string; inner: { index: number; val: Object } }[] { + return mx.range(0, 10).select(t => ({ + name: "n" + t, + inner: { + index: t, + val: {} + } + })).toArray(); + } + + function CreateSimpleClassArray(): SimpleClass[] { + return mx.range(0, 10).select(t => new SimpleClass()).toArray(); + } + + function CreateSimpleClassWithComparerArray(): SimpleClassWithComparer[] { + return mx.range(0, 10).select(t => new SimpleClassWithComparer(t)).toArray(); + } + + function CreateNumberArray(): number[] { + return mx.range(0, 10).toArray(); + } + + function CreateFloatNumberArray(): number[] { + return mx.range(0, 10).select(t => t + 0.1).toArray(); + } + + function CreateStringArray(): string[] { + return mx.range(0, 10).select(t => t + "_string").toArray(); + } + + function CreateDateArray(): Date[] { + return mx.range(0, 10).select(t => new Date(new Date().getTime() + t)).toArray(); + } + + function CreateBooleanArray(): boolean[] { + return mx.range(0, 10).select(t => t % 2 === 0).toArray(); + } + } + + + module CollectionTests { + + QUnit.module("Collection"); + + + QUnit.test("constructor", function (assert) { + + assert.ok(CreateCollection().count() === 5, "initialize a Collection using specified collection!"); + }); + + + QUnit.test("count", function (assert) { + + var _col = CreateCollection(); + assert.ok(_col.count() === 5, "collection containing count!"); + assert.throws(() => new Collection().count(), "throws an error getting count of an empty collection."); + }); + + + QUnit.test("copyTo", function (assert) { + + var _col = CreateCollection(), + _arr = new Array(_col.count()); + + _col.copyTo(_arr, 0); + + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "Collection copy to an array!"); + assert.throws(() => _col.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("collection enumerable", function (assert) { + + var _col = CreateCollection(); + assert.deepEqual(_col.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a collection!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateCollection(): Collection { + return new Collection(mx.range(1, 5)); + } + } + + + module ListTests { + + QUnit.module("List"); + + + QUnit.test("constructor", function (assert) { + assert.ok(new List().count() === 0, "an empty list!"); + assert.ok(new List(10).count() === 10, "an empty list with initial capacity!"); + assert.ok(new List(1, 2, 3, 4, 5).count() === 5, "list initializer!"); + assert.ok(new List(mx.range(0, 10)).count() === 10, "list from an Enumerable!"); + }); + + + QUnit.test("indexer", function (assert) { + + var _list = CreateList(); + + assert.ok(_list[0] === 1, "indexer get!"); + + _list[0] = 0; + assert.ok(_list[0] === 0 && _list.first() === 0, "indexer set!"); + }); + + + QUnit.test("add", function (assert) { + + var _list = new List(); + + _list.add(1); + assert.ok(_list[0] === 1, "add!"); + assert.ok(_list.count() === 1, "add count!"); + }); + + + QUnit.test("addRange", function (assert) { + + var _list = new List(); + + _list.addRange(mx.range(0, 10)); + assert.ok(_list.count() === 10, "add range of numbers!"); + }); + + + QUnit.test("asReadOnly", function (assert) { + + var _rlist = new List(mx.range(0, 10)).asReadOnly(); + + assert.ok(_rlist.count() === 10, "readOnlyCollection count!"); + assert.ok(_rlist[0] === 0, "readOnlyCollection get!"); + }); + + + QUnit.test("binarySearch", function (assert) { + + var _list1 = new List(mx.range(0, 100)), + _list2 = new List<{ index: number }>(mx.range(0, 100).select(t => ({ index: t }))); + + assert.ok(_list1.binarySearch(50) === 50, "binary-search to find an item!"); + assert.ok(_list1.binarySearch(100) < 0, "binary-search item not found!"); + + assert.ok(_list2.binarySearch({ index: 50 }, { compare: (a, b) => a.index - b.index }) === 50, "binary-search find an item with comparer!"); + assert.ok(_list2.binarySearch({ index: 80 }, 50, 40, { compare: (a, b) => a.index - b.index }) === 80, "binary-search find an item with index, count and comparer!"); + }); + + + QUnit.test("clear", function (assert) { + + var _list = CreateList(); + + _list.clear(); + assert.ok(_list.count() === 0, "Clear list!"); + }); + + + QUnit.test("contains", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.contains(3) === true, "list contains!"); + assert.ok(_list.contains(6) === false, "list not containing!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _list = CreateList(), + _arr = new Array(_list.count()); + + _list.copyTo(_arr, 0); + + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "list copyTo an array!"); + }); + + + QUnit.test("exists", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.exists(t => t % 2 === 0), "an even number exists in a list of the first 5 number!"); + assert.ok(_list.exists(t => t > 5) === false, "6 exists in a list of the first 5 number!"); + }); + + + QUnit.test("find", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.find(t => t % 2 === 0) === 2, "find an even number in a list of the first 5 number!"); + assert.ok(_list.find(t => t > 5) === null, "find a number greater than 5 in a list of the first 5 number!"); + }); + + + QUnit.test("findIndex", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.findIndex(t => t % 2 === 0) === 1, "find index of an even numbers in a list of the first 5 number!"); + assert.ok(_list.findIndex(2, t => t % 2 === 0) === 3, "find index of an even numbers in a list of the first 5 number, starting from 2!"); + assert.ok(_list.findIndex(2, 1, t => t % 2 === 0) === -1, "find index of an even numbers in a list of the first 5 number, starting from 3, for 1 attempt!"); + }); + + + QUnit.test("findLast", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.findLast(t => t % 2 === 0) === 4, "find last even number in a list of the first 5 number!"); + assert.ok(_list.findLast(t => t > 5) === null, "find last number greater than 5 in a list of the first 5 number!"); + }); + + + QUnit.test("findLastIndex", function (assert) { + + var _list = new List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + + assert.ok(_list.findLastIndex(t => t % 2 === 0) === 8, "find last index of an even numbers in a list of the first 10 number!"); + assert.ok(_list.findLastIndex(5, t => t % 2 === 0) === 4, "find last index of an even numbers in a list of the first 10 number, starting from 5!"); + assert.ok(_list.findLastIndex(5, 1, t => t % 2 === 0) === -1, "find last index of an even numbers in a list of the first 10 number, starting from 5, for 1 attempt!"); + }); + + + QUnit.test("forEach", function (assert) { + + var _list = CreateList(), + _count = 0; + + _list.forEach(t => _count += t); + + assert.ok(_count === 15, "forEach to get sum of a the items in a list!"); + }); + + + QUnit.test("get", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.get(1) === 2, "get item at index 1 from a list of 5 numbers!"); + assert.throws(() => _list.get(10), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("getRange", function (assert) { + + var _list = CreateList(); + + assert.deepEqual(_list.getRange(0, 3).toArray(), [1, 2, 3], "get range of first 3 items of a list of first 5 numbers!"); + assert.throws(() => _list.getRange(0, 10), "throws an error getting first 10 items from a list of 5 numbers!"); + }); + + + QUnit.test("indexOf", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.indexOf(3) === 2, "get index of 3 in a list of first 5 numbers!"); + assert.ok(_list.indexOf(10) === -1, "get index of 10 in a list of first 5 numbers!"); + assert.ok(_list.indexOf(3, 4) === -1, "get index of 3 in a list of first 5 numbers, starting from index 4!"); + }); + + + QUnit.test("insert", function (assert) { + + var _list = CreateList(); + + _list.insert(3, 0); + + assert.ok(_list.count() === 6, "insert an item in a list of 5 numbers, get count!"); + assert.ok(_list[3] === 0, "insert an item in a list of 5 numbers, get item!"); + assert.throws(() => _list.insert(10, 0), "throws an error inserting in 10th index of a list of 5 numbers!"); + }); + + + QUnit.test("insertRange", function (assert) { + + var _list = CreateList(); + + _list.insertRange(3, mx.range(0, 3)); + + assert.ok(_list.count() === 8, "insert range of items in a list of 5 numbers, get count!"); + assert.ok(_list[3] === 0 && _list[4] === 1 && _list[5] === 2, "insert range of items in a list of 5 numbers, get items!"); + assert.throws(() => _list.insertRange(10, mx.range(0, 3)), "throws an error inserting range of items in 10th index of a list of 5 numbers!"); + }); + + + QUnit.test("lastIndexOf", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.lastIndexOf(3) === 2, "get last index of 3 in a list of first 5 numbers!"); + assert.ok(_list.lastIndexOf(10) === -1, "get last index of 10 in a list of first 5 numbers!"); + assert.ok(_list.lastIndexOf(3, 1) === -1, "get last index of 3 in a list of first 5 numbers, starting from index 1!"); + }); + + + QUnit.test("remove", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.remove(2) === true && _list.count() === 4, "remove an item from a list, get count!"); + assert.ok(_list.remove(10) === false && _list.count() === 4, "remove an item which does not exist in a list, get count!"); + }); + + + QUnit.test("removeAll", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.removeAll(t => t % 2 === 0) === 2 && _list.count() === 3, "remove all even numbers from a list of first 5 numbers, get count!"); + assert.ok(_list.removeAll(t => t % 2 === 0) === 0 && _list.count() === 3, "remove all even numbers from a list of first 3 odd numbers, get count!"); + }); + + + QUnit.test("removeAt", function (assert) { + + var _list = CreateList(); + + _list.removeAt(2); + + assert.ok(_list[2] === 4 && _list.count() === 4, "remove item from 2nd index of a list of first 5 numbers, get count!"); + assert.throws(() => _list.removeAt(10), "throws an error removing item from 10th index of a list of first 5 numbers!"); + }); + + + QUnit.test("removeRange", function (assert) { + + var _list = CreateList(); + + _list.removeRange(1, 3); + + assert.ok(_list[0] === 1 && _list[1] === 5 && _list.count() === 2, "remove range of 3 items, starting from 1st index from a list of first 5 numbers, get count!"); + assert.throws(() => _list.removeRange(10, 10), "throws an error removing a range of items starting from 10th index of a list of first 5 numbers!"); + }); + + + QUnit.test("reverse", function (assert) { + + var _arr = [1, 2, 3, 4, 5], + _list1 = new List(_arr), + _list2 = new List(_arr); + + _list1.reverse(); + _list2.reverse(0, 3); + + assert.deepEqual(_list1.toArray(), [5, 4, 3, 2, 1], "reverse list of 5 first numbers!"); + assert.deepEqual(_list2.toArray(), [3, 2, 1, 4, 5], "reverse first 3 items of a list of 5 first numbers!"); + }); + + + QUnit.test("set", function (assert) { + + var _list = CreateList(); + + _list.set(1, 0); + + assert.ok(_list[1] === 0, "set value at index 1 of a list!"); + assert.throws(() => _list.set(10, 1), "throws an error setting item at index 10 from a list of 5 numbers!"); + }); + + + QUnit.test("sort", function (assert) { + + var _arr = [7, 1, 8, 3, 2, 0, 9, 6, 4, 5], + _list1 = new List(_arr), + _list2 = new List(_arr), + _list3 = new List(_arr), + _list4 = new List(_arr), + _sorter = (a: number, b: number) => a - b; + + _list1.sort(); + _list2.sort(_sorter); + _list3.sort({ compare: _sorter }); + _list4.sort(0, 5, { compare: _sorter }); + + assert.deepEqual(_list1.toArray(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "sort list of first 10 numbers!"); + assert.deepEqual(_list2.toArray(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "sort list of first 10 numbers with a comparison function!"); + assert.deepEqual(_list3.toArray(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "sort list of first 10 numbers with a comparer!"); + assert.deepEqual(_list4.toArray(), [1, 2, 3, 7, 8, 0, 9, 6, 4, 5], "sort 5 first items of list of first 10 numbers with a comparer!"); + }); + + + QUnit.test("toArray", function (assert) { + + var _list = CreateList(); + + assert.deepEqual(_list.toArray(), [1, 2, 3, 4, 5], "converts a list of numbers to an array!"); + }); + + + QUnit.test("trueForAll", function (assert) { + + var _list = CreateList(); + + assert.ok(_list.trueForAll(t => t < 10) === true, "checks whether all items in a list of 5 first numbers are less than 10!"); + assert.ok(_list.trueForAll(t => t < 3) === false, "checks whether all items in a list of 5 first numbers are less than 3!"); + }); + + + QUnit.test("list enumerable", function (assert) { + + var _list = CreateList(); + + assert.deepEqual(_list.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a list!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateList(): List { + return new List(1, 2, 3, 4, 5); + } + } + + + module ReadOnlyCollectionTests { + + QUnit.module("ReadOnlyCollection"); + + + QUnit.test("constructor", function (assert) { + assert.ok(CreateReadOnlyCollection().count() === 5, "initialize a ReadOnlyCollection!"); + assert.throws(() => new ReadOnlyCollection(null), "throws an exception creating an ampty ReadOnlyCollection!"); + }); + + + QUnit.test("indexer", function (assert) { + + var _col = CreateReadOnlyCollection(); + + assert.ok(_col[0] === 1, "indexer get!"); + assert.ok(function () { + try { _col[0] = 0; } + catch (e) { } + return _col[0] === 1; + }, "indexer set!"); + + assert.ok(function () { + try { _col[10] = 0; } + catch (e) { } + return _col[10] === undefined; + }, "out of range indexer set!"); + }); + + + QUnit.test("get", function (assert) { + + var _col = CreateReadOnlyCollection(); + + assert.ok(_col.get(1) === 2, "get item at index 1 from a collection of 5 numbers!"); + assert.throws(() => _col.get(10), "throws error getting item at index 10 from a collection of 5 numbers!"); + }); + + + QUnit.test("contains", function (assert) { + + var _col = CreateReadOnlyCollection(); + + assert.ok(_col.contains(3) === true, "collection contains!"); + assert.ok(_col.contains(6) === false, "collection not containing!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _col = CreateReadOnlyCollection(), + _arr = new Array(_col.count()); + + _col.copyTo(_arr, 0); + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "collection copyTo an array!"); + assert.throws(() => _col.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("indexOf", function (assert) { + + var _col = CreateReadOnlyCollection(); + + assert.ok(_col.indexOf(3) === 2, "get index of 3 in a collection of first 5 numbers!"); + assert.ok(_col.indexOf(10) === -1, "get index of 10 in a collection of first 5 numbers!"); + }); + + + QUnit.test("collection enumerable", function (assert) { + + var _col = CreateReadOnlyCollection(); + + assert.deepEqual(_col.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a collection!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateReadOnlyCollection(): ReadOnlyCollection { + return new ReadOnlyCollection(new List(1, 2, 3, 4, 5)); + } + } + + + module SortedListTests { + + QUnit.module("SortedList"); + + + QUnit.test("constructor", function (assert) { + + var _comparer = Comparer.create((a: number, b: number) => a - b), + _dic = CreateDictionary(), + _s1 = new SortedList(), + _s2 = new SortedList(5), + _s3 = new SortedList(_dic), + _s4 = new SortedList(_comparer), + _s5 = new SortedList(5, _comparer), + _s6 = new SortedList(_dic, _comparer); + + + assert.ok(_s1.count() === 0 && _s1.capacity() === 0, "initialize a SortedList!"); + assert.ok(_s2.count() === 0 && _s2.capacity() === 5, "initialize a SortedList using initial capacity!"); + assert.ok(_s3.count() === 5 && _s3.capacity() === 5, "initialize a SortedList using specified dictionary!"); + assert.ok(_s4.count() === 0 && _s4.capacity() === 0, "initialize a SortedList using specified comparer!"); + assert.ok(_s5.count() === 0 && _s5.capacity() === 5, "initialize a SortedList using using initial capacity and comparer!"); + assert.ok(_s6.count() === 5 && _s6.capacity() === 5, "initialize a SortedList using specified dictionary and comparer!"); + }); + + + QUnit.test("add", function (assert) { + + assert.ok(CreateSortedList().count() == 5, "sorted-list add!"); + assert.throws(() => CreateSortedList().add(1, "AA"), "throws an error adding existing key to the list!"); + }); + + + QUnit.test("get", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.get(1) === "A", "sorted-list get!"); + assert.throws(() => _list.get(10), "throws an error getting invalid key!"); + }); + + + QUnit.test("capacity", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.capacity() > 0, "get sorted-list capacity!"); + + _list.capacity(10); + assert.ok(_list.capacity() === 10, "set sorted-list capacity!"); + }); + + + QUnit.test("clear", function (assert) { + + var _list = CreateSortedList(); + + _list.clear(); + assert.ok(_list.count() === 0 && _list.capacity() === 0, "clear sorted-list!"); + }); + + + QUnit.test("comparer", function (assert) { + + var _comparer = CreateSortedList().comparer(); + + assert.ok(_comparer.compare(5, 1) > 0 && _comparer.compare(1, 5) < 0 && _comparer.compare(1, 1) === 0, "sorted-list comparer!"); + }); + + + QUnit.test("containsKey", function (assert) { + + var _list1 = CreateSortedList(), + _list2 = new SortedList<{ id: number; name: string }, number>({ compare: (a, b) => a.name.localeCompare(b.name) }); + + assert.ok(_list1.containsKey(1) === true, "sorted-list contains key!"); + assert.ok(_list1.containsKey(10) === false, "sorted-list does not contain key!"); + + + _list2.add({ id: 2, name: "B" }, 2); + _list2.add({ id: 5, name: "E" }, 5); + _list2.add({ id: 4, name: "D" }, 4); + _list2.add({ id: 3, name: "C" }, 3); + _list2.add({ id: 1, name: "A" }, 1); + + assert.ok(_list2.containsKey({ id: 3, name: "C" }), "sorted-list contains key using specified comparer"); + }); + + + QUnit.test("containsValue", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.containsValue("A") === true, "sorted-list contains value!"); + assert.ok(_list.containsValue("Z") === false, "sorted-list does not contain value!"); + }); + + + QUnit.test("keys", function (assert) { + + var _list = CreateSortedList(); + + assert.deepEqual(_list.keys().toArray(), [1, 2, 3, 4, 5], "sorted-list keys!"); + assert.deepEqual(new SortedList().keys().toArray(), [], "empty sorted-list keys!"); + }); + + + QUnit.test("values", function (assert) { + + var _list = CreateSortedList(); + + assert.deepEqual(_list.values().toArray(), ["A", "B", "C", "D", "E"], "sorted-list values!"); + assert.deepEqual(new SortedList().values().toArray(), [], "empty sorted-list values!"); + }); + + + QUnit.test("indexOfKey", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.indexOfKey(1) === 0, "sorted-list index of key!"); + assert.ok(_list.indexOfKey(10) < 0, "sorted-list index of invalid key!"); + }); + + + QUnit.test("indexOfValue", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.indexOfValue("A") === 0, "sorted-list index of value!"); + assert.ok(_list.indexOfValue("Z") < 0, "sorted-list index of invalid value!"); + }); + + + QUnit.test("remove", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(_list.remove(1) === true && _list.count() === 4 && _list.indexOfKey(1) < 0, "sorted-list remove key!"); + assert.ok(_list.remove(1) === false && _list.count() === 4, "sorted-list remove invalid key!"); + }); + + + QUnit.test("removeAt", function (assert) { + + var _list = CreateSortedList(); + + _list.removeAt(0); + assert.ok(_list.count() === 4 && _list.indexOfKey(1) < 0, "sorted-list remove at index!"); + assert.throws(() => _list.removeAt(10), "throws an error removing item at invalid index"); + }); + + + QUnit.test("set", function (assert) { + + var _list = CreateSortedList(); + + _list.set(1, "AA"); + assert.ok(_list.count() === 5 && _list.get(1) === "AA", "sorted-list set exisiting key's value!"); + + _list.set(6, "F"); + assert.ok(_list.count() === 6 && _list.get(6) === "F", "sorted-list set new key and value!"); + }); + + + QUnit.test("tryGetValue", function (assert) { + + var _list = CreateSortedList(); + + assert.ok(function () { + var value: string; + var res = _list.tryGetValue(1, val => value = val); + + return res && value === "A"; + + }, "sorted-list tryGetValue, exisiting key!"); + + + assert.ok(function () { + var value: string; + var res = _list.tryGetValue(10, val => value = val); + + return res === false; + + }, "sorted-list tryGetValue, invalid key!"); + }); + + + QUnit.test("sorted-list enumerable", function (assert) { + + var _list = CreateSortedList(); + + assert.deepEqual(_list.select(t => t.key * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a sorted-list!"); + assert.deepEqual(_list.where(t => t.key > 2).select(t => t.value).toArray(), ["C", "D", "E"], "where-select-toArray over a sorted-list!"); + }); + + + QUnit.test("evaluate sorting", function (assert) { + + var _list1 = CreateSortedList(), + _list2 = new SortedList<{ id: number; name: string }, number>({ compare: (a, b) => a.name.localeCompare(b.name) }); + + _list1.remove(5); + _list1.add(6, "F"); + _list1.remove(4); + _list1.add(7, "G"); + _list1.remove(3); + _list1.add(8, "H"); + _list1.remove(2); + _list1.add(9, "I"); + _list1.remove(1); + _list1.add(10, "J"); + + assert.deepEqual(_list1.keys().toArray(), [6, 7, 8, 9, 10], "evaluate sorted keys after multiple add/remove"); + assert.deepEqual(_list1.values().toArray(), ["F", "G", "H", "I", "J"], "evaluate sorted values after multiple add/remove"); + + + + _list2.add({ id: 2, name: "B" }, 2); + _list2.add({ id: 5, name: "E" }, 5); + _list2.add({ id: 4, name: "D" }, 4); + _list2.add({ id: 3, name: "C" }, 3); + _list2.add({ id: 1, name: "A" }, 1); + + assert.deepEqual(_list2.keys().select(t => t.id).toArray(), [1, 2, 3, 4, 5], "evaluate sorted keys after multiple add/remove using specified comparer!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateDictionary(): Dictionary { + var _dic = new Dictionary(); + _dic.add(1, "A"); + _dic.add(2, "B"); + _dic.add(3, "C"); + _dic.add(4, "D"); + _dic.add(5, "E"); + + return _dic; + } + + function CreateSortedList(): SortedList { + var _list = new SortedList(); + _list.add(5, "E"); + _list.add(3, "C"); + _list.add(2, "B"); + _list.add(4, "D"); + _list.add(1, "A"); + + return _list; + } + } + + + module DictionaryTests { + + QUnit.module("Dictionary"); + + + QUnit.test("constructor", function (assert) { + + var _comparer = EqualityComparer.create(o => mx.hash(o), (a, b) => a === b), + _d1 = new Dictionary(), + _d2 = new Dictionary(CreateDictionary()), + _d3 = new Dictionary(_comparer), + _d4 = new Dictionary(5), + _d5 = new Dictionary(5, _comparer), + _d6 = new Dictionary(CreateDictionary(), _comparer); + + + assert.ok(_d1.count() === 0, "initialize a Dictionary!"); + assert.ok(_d2.count() === 5, "initialize a Dictionary using specified dictionary!"); + assert.ok(_d3.count() === 0, "initialize a Dictionary using specified comparer!"); + assert.ok(_d4.count() === 0, "initialize a Dictionary using initial capacity!"); + assert.ok(_d5.count() === 0, "initialize a Dictionary using using initial capacity and comparer!"); + assert.ok(_d6.count() === 5, "initialize a Dictionary using specified dictionary and comparer!"); + }); + + + QUnit.test("add", function (assert) { + var _dic = new Dictionary(); + _dic.add(1, "A"); + + assert.ok(_dic.count() === 1, "ditionary add"); + assert.throws(() => _dic.add(1, "B"), "throws an error adding duplicate key"); + }); + + + QUnit.test("clear", function (assert) { + var _dic = CreateDictionary(); + _dic.clear(); + + assert.ok(_dic.count() === 0, "ditionary clear!"); + }); + + + QUnit.test("containsKey", function (assert) { + + var _dic = CreateDictionary(); + + assert.ok(_dic.containsKey(1) === true, "dictionary contains key!"); + assert.ok(_dic.containsKey(10) === false, "dictionary does not contain key!"); + }); + + + QUnit.test("containsValue", function (assert) { + + var _dic = CreateDictionary(); + + assert.ok(_dic.containsValue("A") === true, "dictionary contains value!"); + assert.ok(_dic.containsValue("Z") === false, "dictionary does not contain value!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _dic = CreateDictionary(), + _arr = new Array(_dic.count()); + + _dic.copyTo(_arr, 0); + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "dictionary copy to an array!"); + assert.throws(() => _dic.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("keys", function (assert) { + + var _dic = CreateDictionary(); + + assert.deepEqual(_dic.keys().toArray(), [1, 2, 3, 4, 5], "dictionary keys!"); + assert.deepEqual(new Dictionary().keys().toArray(), [], "empty dictionary keys!"); + }); + + + QUnit.test("values", function (assert) { + + var _dic = CreateDictionary(); + + assert.deepEqual(_dic.values().toArray(), ["A", "B", "C", "D", "E"], "dictionary values!"); + assert.deepEqual(new Dictionary().values().toArray(), [], "empty dictionary values!"); + }); + + + QUnit.test("get", function (assert) { + + var _dic = CreateDictionary(); + + assert.ok(_dic.get(1) === "A", "dictionary get value!"); + assert.throws(() => _dic.get(10), "throws an error getting non existing key!"); + }); + + + QUnit.test("set", function (assert) { + + var _dic = CreateDictionary(); + + _dic.set(1, "AA"); + assert.ok(_dic.get(1) === "AA", "dictionary set value!"); + + _dic.set(6, "F"); + assert.ok(_dic.count() === 6 && _dic.get(6) === "F", "dictionary set new key and value!"); + }); + + + QUnit.test("tryGetValue", function (assert) { + + var _dic = CreateDictionary(); + + assert.ok(function () { + var value: string; + var res = _dic.tryGetValue(1, val => value = val); + + return res && value === "A"; + + }, "dictionary tryGetValue, exisiting key!"); + + + assert.ok(function () { + var value: string; + var res = _dic.tryGetValue(10, val => value = val); + + return res === false; + + }, "dictionary tryGetValue, invalid key!"); + }); + + + QUnit.test("remove", function (assert) { + + var _dic = CreateDictionary(); + + assert.ok(_dic.remove(1) === true && _dic.count() === 4, "dictionary remove key!"); + assert.ok(_dic.remove(10) === false && _dic.count() === 4, "dictionary remove non existing key!"); + }); + + + QUnit.test("key-value pair", function (assert) { + + var _pair1 = new KeyValuePair(1, "A"), + _pair2 = new KeyValuePair(1, "A"); + + assert.ok(_pair1.key === 1 && _pair1.value === "A", "KeyValuePair get key/value!"); + assert.throws(() => _pair1.key = 2, "throws an error trysing to set KeyValuePair key!"); + assert.throws(() => _pair1.value = "B", "throws an error trysing to set KeyValuePair value!"); + assert.ok(mx.hash(_pair1) === mx.hash(_pair2), "KeyValuePair get hash code!"); + assert.ok(mx.equals(_pair1, _pair2), "KeyValuePair equality check!"); + }); + + + QUnit.test("dictionary enumerable", function (assert) { + + var _dic = CreateDictionary(); + + assert.deepEqual(_dic.select(t => t.key).toArray(), [1, 2, 3, 4, 5], "dictionary select keys, to array!"); + assert.deepEqual(_dic.select(t => t.value).toArray(), ["A", "B", "C", "D", "E"], "dictionary select values, to array!"); + assert.ok(_dic.toArray()[0].key === 1 && _dic.toArray()[0].value === "A", "dictionary select key-value items!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateDictionary(): Dictionary { + var _dic = new Dictionary(); + _dic.add(1, "A"); + _dic.add(2, "B"); + _dic.add(3, "C"); + _dic.add(4, "D"); + _dic.add(5, "E"); + + return _dic; + } + } + + + module HashSetTests { + + QUnit.module("Hashset"); + + + QUnit.test("constructor", function (assert) { + + assert.ok(new HashSet().count() === 0, "initialize an empty HashSet!"); + assert.ok(new HashSet(mx.range(1, 5)).count() === 5, "initialize a HashSet using specified collection!"); + assert.ok(new HashSet(mx.EqualityComparer.defaultComparer).count() === 0, "initialize a HashSet using specified equality comparer!"); + assert.ok(CreateObjectHashSet().count() === 2, "initialize a HashSet using specified collection and equality comparer!"); + }); + + + QUnit.test("add", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.add(6) === true, "add item to a HashSet of numbers!"); + assert.ok(_hash1.add(1) === false, "add existing item to a HashSet of numbers!"); + assert.ok(_hash2.add({ name: "C", value: 5 }) === true, "add item to a HashSet of objects!"); + assert.ok(_hash2.add({ name: "A", value: 5 }) === false, "add an existing item to a HashSet of objects!"); + }); + + + QUnit.test("clear", function (assert) { + + var _hash = CreateNumericHashSet(); + + _hash.clear(); + assert.ok(_hash.count() === 0, "clear a HashSet!"); + }); + + + QUnit.test("contains", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.contains(1) === true, "HashSet of numbers contains an item!"); + assert.ok(_hash1.contains(6) === false, "HashSet of numbers does not contain an item!"); + assert.ok(_hash2.contains({ name: "A", value: 5 }) === true, "HashSet of objects contains an item!"); + assert.ok(_hash2.contains({ name: "C", value: 5 }) === false, "HashSet of objects does not contain an item!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _hash = CreateNumericHashSet(), + _arr = new Array(_hash.count()); + + _hash.copyTo(_arr, 0); + + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "HashSet copy to an array!"); + assert.throws(() => _hash.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("comparer", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.comparer() === mx.EqualityComparer.defaultComparer, "HashSet default comparer!"); + assert.ok(_hash2.comparer().equals({ name: "A", value: 1 }, { name: "A", value: 2 }), "HashSet custom comparer!"); + }); + + + QUnit.test("remove", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.remove(1) === true, "HashSet of numbers remove an item!"); + assert.ok(_hash1.remove(1) === false, "HashSet of numbers remove non existing item!"); + assert.ok(_hash2.remove({ name: "A", value: 1 }) === true, "HashSet of objects remove an item!"); + assert.ok(_hash2.remove({ name: "A", value: 1 }) === false, "HashSet of objects remove non existing item!"); + }); + + + QUnit.test("removeWhere", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.removeWhere(t => t < 3) === 2, "HashSet of numbers remove with predicate, get number of items removed!"); + assert.ok(_hash1.removeWhere(t => t < 3) === 0, "HashSet of numbers remove with invalid predicate, get number of items removed!"); + assert.ok(_hash1.count() === 3, "HashSet of numbers remove with predicate, get count!"); + + assert.ok(_hash2.removeWhere(t => t.value < 3) === 1, "HashSet of objects remove with predicate, get number of items removed!"); + assert.ok(_hash2.removeWhere(t => t.value < 3) === 0, "HashSet of objects remove with invalid predicate, get number of items removed!"); + assert.ok(_hash2.count() === 1, "HashSet of objects remove with predicate, get count!"); + }); + + + QUnit.test("exceptWith", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(), + _hash3 = CreateNumericHashSet(); + + _hash1.exceptWith([1, 2, 3]); + _hash2.exceptWith([{ name: "A", value: 0 }]); + _hash3.exceptWith(CreateNumericHashSet()); + + assert.ok(_hash1.count() === 2 && _hash1.contains(1) === false, "HashSet of numbers except a collection, get count!"); + assert.ok(_hash2.count() === 1 && _hash2.contains({ name: "A", value: 0 }) === false, "HashSet of objects except a collection, get count!"); + assert.ok(_hash3.count() === 0, "HashSet of numbers except an equal set, get count!"); + }); + + + QUnit.test("intersectWith", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(), + _hash3 = CreateNumericHashSet(); + + _hash1.intersectWith([1, 2, 3]); + _hash2.intersectWith([{ name: "A", value: 0 }]); + _hash3.intersectWith(CreateNumericHashSet()); + + assert.ok(_hash1.count() === 3 && _hash1.contains(1) === true, "HashSet of numbers intersect with a collection, get count!"); + assert.ok(_hash2.count() === 1 && _hash2.contains({ name: "A", value: 0 }) === true, "HashSet of objects intersect with a collection, get count!"); + assert.ok(_hash3.count() === 5, "HashSet of numbers intersect with an equal set, get count!"); + }); + + + QUnit.test("isProperSubsetOf", function (assert) { + + var _hash = CreateNumericHashSet(); + + assert.ok(new HashSet().isProperSubsetOf([1, 2, 3]) === true, "an empty set is a proper subset of any other collection!"); + assert.ok(new HashSet().isProperSubsetOf([]) === false, "an empty set is not a proper subset of another empty collection!"); + assert.ok(_hash.isProperSubsetOf([1, 2, 3, 4]) === false, "a hash set is not a proper subset of another collection when count is greater than the number of elements in other!"); + assert.ok(_hash.isProperSubsetOf([1, 2, 3, 4, 5]) === false, "a hash set is not a proper subset of another collection when count is equal to the number of elements in other!"); + assert.ok(_hash.isProperSubsetOf([1, 2, 3, 4, 5, 6]) === true, "hash set proper subset!"); + }); + + + QUnit.test("isProperSupersetOf", function (assert) { + + var _hash = CreateNumericHashSet(); + + assert.ok(new HashSet().isProperSupersetOf([1, 2, 3]) === false, "an empty set is a not superset of any other collection!"); + assert.ok(new HashSet().isProperSupersetOf([]) === false, "an empty set is not a proper superset of another empty collection!"); + assert.ok(_hash.isProperSupersetOf([1, 2, 3, 4, 5, 6]) === false, "a hash set is not a proper superset of another collection when count is less than the number of elements in other!"); + assert.ok(_hash.isProperSupersetOf([1, 2, 3, 4, 5]) === false, "a hash set is not a proper superset of another collection when count is equal to the number of elements in other!"); + assert.ok(_hash.isProperSupersetOf([1, 2, 3]) === true, "hash set proper superset!"); + }); + + + QUnit.test("isSubsetOf", function (assert) { + + var _hash = CreateNumericHashSet(); + + assert.ok(new HashSet().isSubsetOf([1, 2, 3]) === true, "an empty set is a subset of any other collection!"); + assert.ok(new HashSet().isSubsetOf([]) === true, "an empty set is a subset of another empty collection!"); + assert.ok(_hash.isSubsetOf([1, 2, 3, 4]) === false, "a hash set is not a subset of another collection when count is greater than the number of elements in other!"); + assert.ok(_hash.isSubsetOf([1, 2, 3, 4, 5]) === true, "a hash set is a proper subset of another collection when count is equal to the number of elements in other!"); + assert.ok(_hash.isSubsetOf([1, 2, 3, 4, 5, 6]) === true, "hash set subset!"); + }); + + + QUnit.test("isSupersetOf", function (assert) { + + var _hash = CreateNumericHashSet(); + + assert.ok(new HashSet().isSupersetOf([1, 2, 3]) === false, "an empty set is a not superset of any other collection!"); + assert.ok(new HashSet().isSupersetOf([]) === true, "an empty set is superset of another empty collection!"); + assert.ok(_hash.isSupersetOf([1, 2, 3, 4, 5, 6]) === false, "a hash set is not a superset of another collection when count is less than the number of elements in other!"); + assert.ok(_hash.isSupersetOf([1, 2, 3, 4, 5]) === true, "a hash set is a proper superset of another collection when count is equal to the number of elements in other!"); + assert.ok(_hash.isSupersetOf([1, 2, 3]) === true, "hash set superset!"); + }); + + + QUnit.test("overlaps", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.ok(_hash1.overlaps([1, 2, 3]) === true, "HashSet of numbers overlaps with another collection!"); + assert.ok(_hash2.overlaps([{ name: "A", value: 0 }]) === true, "HashSet of objects overlaps with another collection!"); + assert.ok(new HashSet().overlaps([1, 2, 3]) === false, "an empty HashSet does not overlap with another collection!"); + }); + + + QUnit.test("setEquals", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateNumericHashSet(); + + assert.ok(_hash1.setEquals(_hash2) === true, "HashSet of numbers equals with another HashSet!"); + assert.ok(_hash1.setEquals([1, 2, 3, 4, 5]) === true, "HashSet of numbers equals with another collection!"); + assert.ok(new HashSet().setEquals([]) === true, "an empty HashSet equals with an empty collection!"); + assert.ok(new HashSet().setEquals([1, 2, 3]) === false, "an empty HashSet does not equals with another collection!"); + }); + + + QUnit.test("symmetricExceptWith", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(), + _hash3 = CreateNumericHashSet(); + + _hash1.symmetricExceptWith([2, 3, 4]); + _hash2.symmetricExceptWith([{ name: "A", value: 0 }]); + _hash3.exceptWith(CreateNumericHashSet()); + + assert.ok(_hash1.count() === 2, "HashSet of numbers symmetric except another collection, get count!"); + assert.ok(_hash1.contains(1) === true && _hash1.contains(5) === true, "HashSet of numbers symmetric except another collection, check contains!"); + assert.ok(_hash2.count() === 1, "HashSet of objects symmetric except another collection, get count!"); + assert.ok(_hash2.contains({ name: "A", value: 0 }) === false && _hash2.contains({ name: "B", value: 0 }) === true, "HashSet of objects symmetric except another collection, check contains!"); + assert.ok(_hash3.count() === 0, "HashSet of numbers symmetric except an equal set, get count!"); + }); + + + QUnit.test("unionWith", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(), + _hash3 = CreateNumericHashSet(); + + _hash1.unionWith([5, 6, 7, 8]); + _hash2.unionWith([{ name: "A", value: 5 }, { name: "B", value: 6 }, { name: "C", value: 7 }, { name: "D", value: 8 }]); + _hash3.unionWith(CreateNumericHashSet()); + + assert.ok(_hash1.count() === 8, "HashSet of numbers union with another collection, get count!"); + assert.ok(_hash1.contains(1) === true && _hash1.contains(8) === true, "HashSet of numbers union with another collection, check contains!"); + assert.ok(_hash2.count() === 4, "HashSet of objects union with another collection, get count!"); + assert.ok(_hash2.contains({ name: "A", value: 0 }) === true && _hash2.contains({ name: "D", value: 0 }) === true, "HashSet of objects union with another collection, check contains!"); + assert.ok(_hash3.count() === 5, "HashSet of numbers union with an equal set, get count!"); + }); + + + QUnit.test("set enumerable", function (assert) { + + var _hash1 = CreateNumericHashSet(), + _hash2 = CreateObjectHashSet(); + + assert.deepEqual(_hash1.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a HashSet of numbers!"); + assert.deepEqual(_hash2.select(t => t.value * 2).where(t => t > 5).toArray(), [6], "select-where-toArray over a HashSet of objects!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateNumericHashSet(): HashSet { + return new HashSet(mx.range(1, 5)); + } + + function CreateObjectHashSet(): HashSet { + + var _items: SimpleObject[] = [{ name: "A", value: 1 }, { name: "A", value: 2 }, { name: "B", value: 3 }, { name: "B", value: 4 }], + _comparer = EqualityComparer.create(obj => mx.hash(obj.name), (a, b) => a.name === b.name); + + return new HashSet(_items, _comparer); + } + } + + + module LinkedListTests { + + QUnit.module("LinkedList"); + + + QUnit.test("constructor", function (assert) { + + assert.ok(new LinkedList().count() === 0, "initialize an empty LinkedList!"); + assert.ok(CreateLinkedList().count() === 5, "initialize a LinkedList using specified collection!"); + }); + + + QUnit.test("add", function (assert) { + + var _list = CreateLinkedList(); + + _list.add(6); + assert.ok(_list.count() === 6, "add an item to a LinkedList!"); + }); + + + QUnit.test("clear", function (assert) { + + var _list = CreateLinkedList(); + + _list.clear(); + assert.ok(_list.count() === 0, "clear a LinkedList!"); + }); + + + QUnit.test("contains", function (assert) { + + var _list = CreateLinkedList(); + + assert.ok(_list.contains(1) && _list.contains(5), "LinkedList contains an item!"); + assert.ok(_list.contains(10) === false, "LinkedList does not contains an item!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _list = CreateLinkedList(), + _arr = new Array(_list.count()); + + _list.copyTo(_arr, 0); + + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "LinkedList copy to an array!"); + assert.throws(() => _list.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("getFirst", function (assert) { + + var _list = CreateLinkedList(); + + assert.ok(_list.getFirst().value() === 1, "LinkedList first item!"); + assert.ok(new LinkedList().getFirst() === null, "empty LinkedList first item!"); + }); + + + QUnit.test("getLast", function (assert) { + + var _list = CreateLinkedList(); + + assert.ok(_list.getLast().value() === 5, "LinkedList last item!"); + assert.ok(new LinkedList().getLast() === null, "empty LinkedList last item!"); + }); + + + QUnit.test("addAfter", function (assert) { + + var _list = CreateLinkedList(), + _first = _list.getFirst(), + _node = new LinkedListNode(6); + + _list.addAfter(_first, _node); + _list.addAfter(_first, 7); + + assert.ok(_list.count() === 7, "LinkedList add after item, get count!"); + assert.ok(_list.contains(6) && _list.contains(7), "LinkedList add after item, check contains!"); + }); + + + QUnit.test("addBefore", function (assert) { + + var _list = CreateLinkedList(), + _last = _list.getLast(), + _node = new LinkedListNode(6); + + _list.addBefore(_last, _node); + _list.addBefore(_last, 7); + + assert.ok(_list.count() === 7, "LinkedList add before item, get count!"); + assert.ok(_list.contains(6) && _list.contains(7), "LinkedList add before item, check contains!"); + }); + + + QUnit.test("addFirst", function (assert) { + + var _list = CreateLinkedList(), + _node = new LinkedListNode(0); + + _list.addFirst(_node); + _list.addFirst(-1); + + assert.ok(_list.count() === 7, "LinkedList add first, get count!"); + assert.ok(_list.contains(0) && _list.contains(-1), "LinkedList add first, check contains!"); + assert.ok(_list.getFirst().value() === -1, "LinkedList add first, get first!"); + }); + + + QUnit.test("addLast", function (assert) { + + var _list = CreateLinkedList(), + _node = new LinkedListNode(6); + + _list.addLast(_node); + _list.addLast(7); + + assert.ok(_list.count() === 7, "LinkedList add last, get count!"); + assert.ok(_list.contains(6) && _list.contains(7), "LinkedList add last, check contains!"); + assert.ok(_list.getLast().value() === 7, "LinkedList add last, get last!"); + }); + + + QUnit.test("find", function (assert) { + + var _list = CreateLinkedList(); + + assert.ok(_list.find(4).value() === 4, "LinkedList find an item!"); + assert.ok(_list.find(10) === null, "LinkedList does not find an item!"); + }); + + + QUnit.test("findLast", function (assert) { + + var _list = CreateLinkedList(), + _node = new LinkedListNode(1); + + _list.addLast(_node); + + assert.ok(_list.findLast(1) === _node, "LinkedList find last!"); + assert.ok(_list.findLast(10) === null, "LinkedList does not find last item!"); + }); + + + QUnit.test("remove", function (assert) { + + var _list = CreateLinkedList(), + _last = _list.getLast(); + + assert.ok(_list.remove(1) === true, "LinkedList remove an item!"); + assert.ok(_list.remove(1) === false, "LinkedList remove non existing item!"); + assert.ok(_list.remove(_last) === true, "LinkedList remove a node!"); + assert.throws(() => _list.remove(_last), "throws an error when removing non existing or invalid node!"); + assert.ok(_list.count() === 3, "LinkedList remove, get count!"); + }); + + + QUnit.test("removeFirst", function (assert) { + + var _list = CreateLinkedList(); + + _list.removeFirst(); + + assert.ok(_list.count() === 4 && _list.contains(1) === false, "LinkedList remove first node!"); + assert.throws(() => new LinkedList().removeFirst(), "throws an error removing from an empty linked list!"); + }); + + + QUnit.test("removeLast", function (assert) { + + var _list = CreateLinkedList(); + + _list.removeLast(); + + assert.ok(_list.count() === 4 && _list.contains(5) === false, "LinkedList remove last node!"); + assert.throws(() => new LinkedList().removeLast(), "throws an error removing from an empty linked list!"); + }); + + + QUnit.test("linked-list enumerable", function (assert) { + + var _list = CreateLinkedList(); + assert.deepEqual(_list.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a linked-list!"); + }); + + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateLinkedList(): LinkedList { + return new LinkedList(mx.range(1, 5)); + } + } + + + module QueueTests { + + QUnit.module("Queue"); + + + QUnit.test("constructor", function (assert) { + + assert.ok(new Queue().count() === 0, "initialize an empty Queue!"); + assert.ok(CreateQueue().count() === 5, "initialize a Queue using specified collection!"); + }); + + + QUnit.test("clear", function (assert) { + + var _queue = CreateQueue(); + + _queue.clear(); + assert.ok(_queue.count() === 0, "clears a Queue!"); + }); + + + QUnit.test("contains", function (assert) { + + var _queue = CreateQueue(); + + assert.ok(_queue.contains(1) === true, "queue containing an item!"); + assert.ok(_queue.contains(10) === false, "queue does not contain an item!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _queue = CreateQueue(), + _arr = new Array(_queue.count()); + + _queue.copyTo(_arr, 0); + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "queue copy to an array!"); + assert.throws(() => _queue.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("dequeue", function (assert) { + + var _queue = CreateQueue(); + + assert.ok(_queue.dequeue() === 1, "queue dequeue an item!"); + + _queue.clear(); + assert.throws(() => _queue.dequeue(), "throws an error dequeue from empty queue!"); + }); + + + QUnit.test("enqueue", function (assert) { + + var _queue = CreateQueue(); + + _queue.enqueue(6); + assert.ok(_queue.count() === 6 && _queue.peek() === 1, "queue dequeue an item!"); + }); + + + QUnit.test("peek", function (assert) { + + var _queue = CreateQueue(); + + assert.ok(_queue.peek() === 1, "queue peek an item!"); + + _queue.clear(); + assert.throws(() => _queue.peek(), "throws an error peek from empty queue!"); + }); + + + QUnit.test("toArray", function (assert) { + + var _queue = CreateQueue(); + + assert.deepEqual(_queue.toArray(), [1, 2, 3, 4, 5], "queue to array!"); + }); + + + QUnit.test("queue enumerable", function (assert) { + + var _queue = CreateQueue(); + + assert.deepEqual(_queue.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a queue!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateQueue(): Queue { + return new Queue(mx.range(1, 5)); + } + } + + + module StackTests { + + QUnit.module("Stack"); + + + QUnit.test("constructor", function (assert) { + + assert.ok(new Stack().count() === 0, "initialize an empty Stack!"); + assert.ok(CreateStack().count() === 5, "initialize a Stack using specified collection!"); + }); + + + QUnit.test("clear", function (assert) { + + var _stack = CreateStack(); + + _stack.clear(); + assert.ok(_stack.count() === 0, "clears a Stack!"); + }); + + + QUnit.test("contains", function (assert) { + + var _stack = CreateStack(); + + assert.ok(_stack.contains(1) === true, "stack containing an item!"); + assert.ok(_stack.contains(10) === false, "stack does not contain an item!"); + }); + + + QUnit.test("copyTo", function (assert) { + + var _stack = CreateStack(), + _arr = new Array(_stack.count()); + + _stack.copyTo(_arr, 0); + assert.deepEqual(_arr, [1, 2, 3, 4, 5], "stack copy to an array!"); + assert.throws(() => _stack.copyTo([], 0), "throws an error when the number of elements is greater than the number of elements that the destination array can contain!"); + }); + + + QUnit.test("peek", function (assert) { + + var _stack = CreateStack(); + + assert.ok(_stack.peek() === 5, "stack peek an item!"); + + _stack.clear(); + assert.throws(() => _stack.peek(), "throws an error peek from empty stack!"); + }); + + + QUnit.test("pop", function (assert) { + + var _stack = CreateStack(); + + assert.ok(_stack.pop() === 5, "stack pop an item!"); + + _stack.clear(); + assert.throws(() => _stack.pop(), "throws an error pop from empty stack!"); + }); + + + QUnit.test("push", function (assert) { + + var _stack = CreateStack(); + + _stack.push(6); + assert.ok(_stack.count() === 6 && _stack.peek() === 6, "stack push an item!"); + }); + + + QUnit.test("toArray", function (assert) { + + var _stack = CreateStack(); + + assert.deepEqual(_stack.toArray(), [1, 2, 3, 4, 5], "stack to array!"); + }); + + + QUnit.test("stack enumerable", function (assert) { + + var _stack = CreateStack(); + + assert.deepEqual(_stack.select(t => t * 2).where(t => t > 5).toArray(), [6, 8, 10], "select-where-toArray over a stack!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateStack(): Stack { + return new Stack(mx.range(1, 5)); + } + } + + + module LookupTests { + + QUnit.module("Lookup"); + + + QUnit.test("contains", function (assert) { + + var _lookup = CreateLookup(); + + assert.ok(_lookup.contains(1) === true, "lookup contains an item!"); + assert.ok(_lookup.contains(10) === false, "lookup does not an item!"); + }); + + + QUnit.test("count", function (assert) { + + var _lookup = CreateLookup(); + + assert.ok(_lookup.count() === 4, "lookup count!"); + }); + + + QUnit.test("get", function (assert) { + + var _lookup = CreateLookup(); + + assert.ok(_lookup.get(1).count() === 2, "lookup get an item!"); + assert.ok(_lookup.get(10).count() === 0, "lookup get non existing item!"); + }); + + + QUnit.test("lookup enumerable", function (assert) { + + var _lookup = CreateLookup(); + + assert.deepEqual(_lookup.select(t => t.key).toArray(), [1, 2, 3, 4], "lookup select keys, to array!"); + assert.deepEqual(_lookup.selectMany(t => t).toArray(), [1, 1, 2, 3, 3, 4, 4, 4], "lookup select all items, to array!"); + assert.deepEqual(_lookup.select(t => t.count()).toArray(), [2, 1, 2, 3], "lookup select items count!"); + }); + + + + /* Factory methods + ---------------------------------------------------------------------- */ + + function CreateLookup(): Lookup { + return mx([1, 1, 2, 3, 3, 4, 4, 4]).toLookup(t => t); + } + } +} \ No newline at end of file diff --git a/multiplexjs/multiplexjs.d.ts b/multiplexjs/multiplexjs.d.ts new file mode 100644 index 000000000..dc39fe6b6 --- /dev/null +++ b/multiplexjs/multiplexjs.d.ts @@ -0,0 +1,2551 @@ +// Type definitions for Multiplex.js 0.9 +// Project: http://github.com/multiplex/multiplex.js +// Definitions by: Kamyar Nazeri +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + + +declare var multiplex: multiplex.MultiplexStatic; + + +// Support AMD require +declare module 'multiplex' { + export = multiplex; +} + + +// Collapse multiplex into mx +import mx = multiplex; + + +// ES6 compatibility +interface Array extends multiplex.Iterable { } +interface String extends multiplex.Iterable { } + + + +declare module multiplex { + + /** + * ES6 Iterable + */ + interface Iterable { + "@@iterator"(): Iterator + } + interface Iterator { + next(): IteratorResult; + return?(value?: any): IteratorResult; + throw?(e?: any): IteratorResult; + } + interface IteratorResult { + done: boolean; + value?: T; + } + + + + /** + * Supports a simple iteration over a collection. + */ + interface Enumerator { + + /** + * Advances the enumerator to the next element of the collection. + */ + next(): boolean; + + /** + * Gets the element in the collection at the current position of the enumerator. + */ + current: T; + } + interface EnumeratorConstructor { + new (generator: (yielder: (value: T) => T) => any): Enumerator; + } + + + + /** + * Exposes the enumerator, which supports a simple iteration over a collection of a specified type. + * Enumerable uses ES6 Iteration protocol. + */ + interface Enumerable extends Iterable { + + /** + * Returns an enumerator that iterates through the collection. + */ + getEnumerator(): Enumerator; + } + interface EnumerableConstructor { + + /** + * Exposes the enumerator, which supports an iteration over the specified Enumerable object. + * @param obj An Iterable object. eg. Enumerable, Array, String, Set, Map, Iterable & Generators + */ + new (obj: Iterable): Enumerable; + + + /** + * Defines an enumerator, which supports an iteration over the specified Generator function. + * @param factory An Enumerator factory function. + */ + new (factory: () => Enumerator): Enumerable; + + /** + * Defines an enumerator, which supports an iteration over the items of the specified Array-like object. + * An Array-like object is an object which has the "length" property and indexed properties access, eg. jQuery + * @param obj An Array-like object. + */ + new (obj: ArrayLike): Enumerable; + + /** + * Defines an enumerator, which supports an iteration over the arguments local variable available within all functions. + * @param obj arguments local variable available within all functions. + */ + new (obj: IArguments): Enumerable; + + /** + * Defines an enumerator, which supports an iteration over the properties of the specified object. + * @param obj A regular Object. + */ + new (obj: Object): Enumerable>; + + + + + /** + * Returns an empty Enumerable. + */ + empty(): Enumerable; + + /** + * Detects if an object is Enumerable. + * @param obj An object to check its Enumerability. + */ + is(obj: any): boolean; + + /** + * Generates a sequence of integral numbers within a specified range. + * @param start The value of the first integer in the sequence. + * @param count The number of sequential integers to generate. + */ + range(start: number, count: number): Enumerable; + + /** + * Generates a sequence that contains one repeated value. + * @param element The value to be repeated. + * @param count The number of times to repeat the value in the generated sequence. + */ + repeat(element: T, count: number): Enumerable; + } + + + + /** + * Defines a method that a type implements to compare two objects. + */ + interface Comparer { + /** + * Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other. + * returns An integer that indicates the relative values of x and y, as shown in the following table: + * Less than zero x is less than y. + * Zero x equals y. + * Greater than zero x is greater than y.. + * @param x The first object to compare. + * @param y The second object to compare. + */ + compare(x: T, y: T): number; + } + interface ComparerConstructor { + + /** + * Returns a default sort order comparer for the type specified by the generic argument. + */ + defaultComparer: Comparer; + + /** + * Creates a comparer by using the specified comparison. + * @param comparison The comparison to use. + */ + create(comparison: (x: T, y: T) => number): Comparer; + } + + + + /** + * Provides a base class for implementations of the EqualityComparer. + */ + interface EqualityComparer { + + /** + * Determines whether the specified objects are equal. + * @param x The first object of type Object to compare. + * @param y The second object of type Object to compare. + */ + equals(x: T, y: T): boolean; + + + /** + * Returns a hash code for the specified object. + * @param obj The Object for which a hash code is to be returned. + */ + hash(obj: T): number + } + interface EqualityComparerConstructor { + + /** + * Gets a default equality comparer for the type specified by the generic argument. + */ + defaultComparer: EqualityComparer; + + + /** + * Creates an EqualityComparer by using the specified equality and hashCodeProvider. + * @param hashCodeProvider The hashCodeProvider to use for a hash code is to be returned. + * @param equality The equality function. + */ + create(hashCodeProvider: (obj: T) => number, equality: (x: T, y: T) => boolean): EqualityComparer; + } + + + + /** + * Initializes a new instance of the abstract Collection class. + */ + interface Collection extends Enumerable { + + /** + * Gets the number of elements contained in the Collection. + */ + count(): number; + + + /** + * Copies the Collection to an existing one-dimensional Array, starting at the specified array index. + * @param array The one-dimensional Array that is the destination of the elements copied from Dictionary keys. + * @param arrayIndex The zero-based index in array at which copying begins. + */ + copyTo(array: T[], arrayIndex: number): void + } + interface CollectionConstructor { + + /** + * Initializes a new instance of the Collection class that is empty. + */ + new (): Collection + + + /** + * Initializes a new instance of the Collection class that is wrapper around the specified Enumerable. + * @param value The Iterable to wrap. + */ + new (value: Iterable): Collection + } + + + + /** + * Initializes a new instance of the abstract Collection class. + */ + interface ReadOnlyCollection extends Collection { + + /** + * Gets the element at the specified index. + * @param index The zero-based index of the element to get. + */ + [index: number]: T; + + + /** + * Gets the element at the specified index. + * @param index The zero-based index of the element to get. + */ + get(index: number): T + + + /** + * Determines whether the ReadOnlyCollection contains a specific value. + * @param item The object to locate in the ReadOnlyCollection. + */ + contains(item: T): boolean + + + /** + * Searches for the specified object and returns the zero-based index of the first occurrence within the entire ReadOnlyCollection. + * @param item The object to locate in the ReadOnlyCollection. + */ + indexOf(item: T): number + } + interface ReadOnlyCollectionConstructor { + + /** + * Initializes a new instance of the ReadOnlyCollection class that is a read-only wrapper around the specified list. + * @param list The list to wrap. + */ + new (list: List): ReadOnlyCollection + } + + + + /** + * Represents a strongly typed list of objects that can be accessed by index. + */ + interface List extends Collection { + + /** + * Gets the element at the specified index. + * @param index The zero-based index of the element to get. + */ + [index: number]: T; + + + /** + * Adds an object to the end of the List. + * @param item The object to be added to the end of the List. + */ + add(item: T): void + + + /** + * Adds the elements of the specified collection to the end of the List. + * @param collection The collection whose elements should be added to the end of the List. + */ + addRange(collection: Iterable): void + + + /** + * Returns a read-only wrapper for the current list. + */ + asReadOnly(): ReadOnlyCollection + + + /** + * Searches the entire sorted List for an element using the default comparer and returns the zero-based index of the element. + * Returns The zero-based index of item in the sorted List, if item is found; otherwise, a negative number + * that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, + * the bitwise complement of List.count(). + * @param item The object to locate. The value can be null for reference types. + */ + binarySearch(item: T): number + + + /** + * Searches the entire sorted List for an element using the specified comparer and returns the zero-based index of the element. + * returns The zero-based index of item in the sorted List, if item is found; otherwise, a negative number + * that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, + * the bitwise complement of List.count(). + * @param item The object to locate. The value can be null for reference types. + * @param comparer The Comparer implementation to use when comparing elements. + */ + binarySearch(item: T, comparer: Comparer): number + + + /** + * Searches a range of elements in the sorted List for an element using the specified comparer and returns the zero-based index of the element. + * returns The zero-based index of item in the sorted List, if item is found; otherwise, a negative number + * that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, + * the bitwise complement of List.count(). + * @param item The object to locate. The value can be null for reference types. + * @param index The zero-based starting index of the range to search. + * @param count The length of the range to search. + * @param comparer The Comparer implementation to use when comparing elements. + */ + binarySearch(item: T, index: number, count: number, comparer: Comparer): number + + + /** + * Removes all items from the List. + */ + clear(): void + + + /** + * Determines whether the List contains elements that match the conditions defined by the specified predicate. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + exists(match: (item: T) => boolean): boolean + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + find(match: (item: T) => boolean): T + + + /** + * Retrieves all the elements that match the conditions defined by the specified predicate. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findAll(match: (item: T) => boolean): List + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the first occurrence within the entire List, if found; otherwise, –1. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findIndex(match: (item: T) => boolean): number + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the first occurrence within the range of elements + * in the List that extends from the specified index to the last element, if found; otherwise, –1. + * @param startIndex The zero-based starting index of the search. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findIndex(startIndex: number, match: (item: T) => boolean): number + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the first occurrence within the range of elements + * in the List that starts at the specified index and contains the specified number of elements, if found; otherwise, –1. + * @param startIndex The zero-based starting index of the search. + * @param count The number of elements in the section to search. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findIndex(startIndex: number, count: number, match: (item: T) => boolean): number + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the last occurrence within the entire List. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findLast(match: (item: T) => boolean): T + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the last occurrence within the entire List, if found; otherwise, –1. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findLastIndex(match: (item: T) => boolean): number + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the last occurrence within the range of elements + * in the List that extends from the first element to the specified index, if found; otherwise, –1. + * @param startIndex The zero-based starting index of the search. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findLastIndex(startIndex: number, match: (item: T) => boolean): number + + + /** + * Searches for an element that matches the conditions defined by the specified predicate, + * and returns the zero-based index of the last occurrence within the range of elements + * in the List that contains the specified number of elements and ends at the specified index, if found; otherwise, –1. + * @param startIndex The zero-based starting index of the search. + * @param count The number of elements in the section to search. + * @param match The predicate function that defines the conditions of the elements to search for. + */ + findLastIndex(startIndex: number, count: number, match: (item: T) => boolean): number + + + /** + * Performs the specified action on each element of the List. + * @param action The action function to perform on each element of the List. + */ + forEach(action: (item: T) => void): void + + + /** + * Gets the element at the specified index. + * @param index The zero-based index of the element to get. + */ + get(index: number): T + + + /** + * Creates a shallow copy of a range of elements in the source List. + * @param index The zero-based List index at which the range starts. + * @param count The number of elements in the range. + */ + getRange(index: number, count: number): List + + + /** + * Searches for the specified object and returns the zero-based index of the first occurrence within the entire List, if found; otherwise, –1. + * @param item The object to locate in the List. + */ + indexOf(item: T): number + + + /** + * Searches for the specified object and returns the zero-based index of the first occurrence within + * the range of elements in the List that extends from the specified index to the last element, if found; otherwise, –1. + * @param item The object to locate in the List. + * @param index The zero-based starting index of the search. 0 (zero) is valid in an empty list. + */ + indexOf(item: T, index: number): number + + + /** + * Inserts an element into the List at the specified index. + * @param index The zero-based index at which item should be inserted. + * @param item The object to insert. The value can be null for reference types. + */ + insert(index: number, item: T): void + + + /** + * Inserts the elements of a collection into the List at the specified index. + * @param index The zero-based index at which item should be inserted. + * @param collection The collection whose elements should be inserted into the List. + */ + insertRange(index: number, collection: Iterable): void + + + /** + * Gets an Array wrapper around the List. + */ + items(): T[] + + + /** + * Searches for the specified object and returns the zero-based index of the last occurrence within the entire List, if found; otherwise, –1. + * @param item The object to locate in the List. + */ + lastIndexOf(item: T): number + + + /** + * Searches for the specified object and returns the zero-based index of the last occurrence + * within the range of elements in the List that extends from the specified index to the last element if found; otherwise, –1. + * @param item The object to locate in the List. + * @param index The zero-based starting index of the search. 0 (zero) is valid in an empty list. + */ + lastIndexOf(item: T, index: number): number + + + /** + * Removes the first occurrence of a specific object from the List. + * @param item The object to remove from the List. + */ + remove(item: T): boolean + + + /** + * Removes all the elements that match the conditions defined by the specified predicate. + * @param match The predicate function that defines the conditions of the elements to remove. + */ + removeAll(match: (item: T) => boolean): number + + + /** + * Removes the element at the specified index of the List. + * @param index The zero-based index of the element to remove. + */ + removeAt(index: number): void + + + /** + * Removes a range of elements from the List. + * @param index The zero-based index of the element to remove. + * @param count The number of elements to remove. + */ + removeRange(index: number, count: number): void + + + /** + * Reverses the order of the elements in the entire List + */ + reverse(): any + + + /** + * Reverses the order of the elements in the entire List + * @param index The zero-based starting index of the range to reverse. + * @param count The number of elements in the range to reverse. + */ + reverse(index: number, count: number): void + + + /** + * Sets the element at the specified index. + * @param index The zero-based index of the element to set. + * @param item The object to be added at the specified index. + */ + set(index: number, value: T): void + + + /** + * Sorts the elements in the entire List using the default comparer. + */ + sort(): void + + + /** + * Sorts the elements in the entire List using the specified Comparison. + * @param comparison The comparison function to use when comparing elements. + */ + sort(comparison: (x: T, y: T) => number): void + + + /** + * Sorts the elements in the entire List using the specified comparer. + * @param comparer The Comparer implementation to use when comparing elements. + */ + sort(comparer: Comparer): void + + + /** + * Sorts the elements in a range of elements in List using the specified comparer. + * @param index The zero-based starting index of the range to sort. + * @param count The length of the range to sort. + * @param comparer The Comparer implementation to use when comparing elements. + */ + sort(index: number, count: number, comparer: Comparer): void + + + /** + * Copies the elements of the List to a new array. + */ + toArray(): T[] + + + /** + * Determines whether every element in the List matches the conditions defined by the specified predicate. + * @param match The Predicate function that defines the conditions to check against the elements. + */ + trueForAll(match: (item: T) => boolean): boolean + } + interface ListConstructor { + + /** + * Initializes a new instance of the List class that is empty. + */ + new (): List + + + /** + * Initializes a new instance of the List class that is empty and has the specified initial capacity. + * @param capacity The number of elements that the new list can initially store. + */ + new (capacity: number): List + + + /** + * Initializes a new instance of the List class that contains elements copied from the specified arguments + * @param args Arbitrary number of arguments to copy to the new list. + */ + new (...args: T[]): List + + + /** + * Initializes a new instance of the List class that contains elements copied from the specified collection + * and has sufficient capacity to accommodate the number of elements copied. + * @param collection The collection whose elements are copied to the new list. + */ + new (collection: Iterable): List + } + + + + /** + * Represents a collection of key/value pairs that are sorted by key based on the associated Comparer implementation. + */ + interface SortedList extends Collection> { + + /** + * Adds an element with the specified key and value into the SortedList. + * @param key The key of the element to add. + * @param value The value of the element to add. The value can be null for reference types. + */ + add(key: TKey, value: TValue): void + + + /** + * Gets the value associated with the specified key. + * @param key The key whose value to get. + */ + get(key: TKey): TValue + + + /** + * Gets or sets the number of elements that the SortedList can contain. + * @param value The number of elements that the SortedList can contain. + */ + capacity(value?: number): number + + + /** + * Removes all elements from the SortedList. + */ + clear(): void + + + /** + * Gets the Comparer for the sorted list. + */ + comparer(): Comparer + + + /** + * Determines whether the SortedList contains a specific key. + * @param key The key to locate in the SortedList. + */ + containsKey(key: TKey): boolean + + + /** + * Determines whether the SortedList contains a specific value. + * @param value The value to locate in the SortedList. + */ + containsValue(value: TValue): boolean + + + /** + * Gets a collection containing the keys in the SortedList, in sorted order. + */ + keys(): Collection + + + /** + * Gets a collection containing the values in the SortedLis. + */ + values(): Collection + + + /** + * Searches for the specified key and returns the zero-based index within the entire SortedList. + * @param key The key to locate in the SortedList. + */ + indexOfKey(key: TKey): number + + + /** + * Searches for the specified value and returns the zero-based index of the first occurrence within the entire SortedList. + * @param value The value to locate in the SortedList. + */ + indexOfValue(value: TValue): number + + + /** + * Removes the element with the specified key from the SortedList. + * Returns true if the element is successfully removed; otherwise, false. This method also returns false if key was not found in the original SortedList. + * @param key The key of the element to remove. + */ + remove(key: TKey): boolean + + + /** + * Removes the element at the specified index of the SortedList. + * @param index The zero-based index of the element to remove. + */ + removeAt(index: number): void + + + /** + * Sets the value associated with the specified key. + * @param key The key whose value to get or set. + * @param value The value associated with the specified key. + */ + set(key: TKey, value: TValue): void + + + /** + * Sets the capacity to the actual number of elements in the SortedList, if that number is less than 90 percent of current capacity. + */ + trimExcess(): void + + + /** + * Gets the value associated with the specified key. + * @param key The key whose value to get. + * @param callback When this method returns, callback method is called with the value + * associated with the specified key, if the key is found; otherwise, null for the type of the value parameter. + */ + tryGetValue(key: TKey, callback: (value: TValue) => void): boolean + } + interface SortedListConstructor { + + /** + * Initializes a new instance of the SortedList class that is empty, + * has the default initial capacity, and uses the default Comparer. + */ + new (): SortedList + + + /** + * Initializes a new instance of the SortedList class that contains elements copied from the specified Dictionary, + * has sufficient capacity to accommodate the number of elements copied, and uses the default Comparer. + * @param dictionary The Dictionary whose elements are copied to the new SortedList. + */ + new (dictionary: Dictionary): SortedList + + + /** + * Initializes a new instance of the SortedList class that is empty, + * has the default initial capacity, and uses the specified Comparer. + * @param comparer The Comparer implementation to use when comparing keys.-or-null to use the default Comparer for the type of the key. + */ + new (comparer: Comparer): SortedList + + + /** + * Initializes a new instance of the SortedList class that is empty, + * has the specified initial capacity, and uses the default Comparer. + * @param capacity The initial number of elements that the SortedList can contain. + */ + new (capacity: number): SortedList + + + /** + * Initializes a new instance of the SortedList class that contains elements copied from the specified Dictionary, + * has sufficient capacity to accommodate the number of elements copied, and uses the specified Comparer. + * @param dictionary The Dictionary whose elements are copied to the new SortedList. + * @param comparer The Comparer implementation to use when comparing keys.-or-null to use the default Comparer for the type of the key. + */ + new (dictionary: Dictionary, comparer: Comparer): SortedList + + + /** + * Initializes a new instance of the SortedList class that is empty, + * has the specified initial capacity, and uses the specified Comparer. + * @param capacity The initial number of elements that the SortedList can contain. + * @param comparer The Comparer implementation to use when comparing keys.-or-null to use the default Comparer for the type of the key. + */ + new (capacity: number, comparer: Comparer): SortedList + } + + + + /** + * Defines a key/value pair that can be set or retrieved. + */ + interface KeyValuePair { + + /** + * Gets the key in the key/value pair. + */ + key: TKey; + + + /** + * Gets the value in the key/value pair. + */ + value: TValue; + } + interface KeyValuePairConstructor { + + /** + * Initializes a new instance of the KeyValuePair with the specified key and value. + * @param key The object defined in each key/value pair. + * @param value The definition associated with key. + */ + new (key: TKey, value: TValue): KeyValuePair + } + + + + /** + * Represents a collection of keys and values. + */ + interface Dictionary extends Collection> { + + /** + * Adds an element with the provided key and value to the Dictionary. + * @param key The object to use as the key of the element to add. + * @param value The object to use as the value of the element to add. + */ + add(key: TKey, value: TValue): void + + + /** + * Removes all keys and values from the Dictionary. + */ + clear(): void + + + /** + * Determines whether the Dictionary contains the specified key. + * @param key The key to locate in the Dictionary. + */ + containsKey(key: TKey): boolean + + + /** + * Determines whether the Dictionary contains a specific value. + * @param value The value to locate in the Dictionary. + */ + containsValue(value: TValue): boolean + + + /** + * Copies the Dictionary keys to an existing one-dimensional Array, starting at the specified array index. + * @param array The one-dimensional Array that is the destination of the elements copied from Dictionary keys. + * @param arrayIndex The zero-based index in array at which copying begins. + */ + copyTo(array: TKey[], arrayIndex: number): void + copyTo(array: KeyValuePair[], arrayIndex: number): void + + + /** + * Gets a Collection containing the keys of the Dictionary. + */ + keys(): Collection + + + /** + * Gets a Collection containing the values in the Dictionary. + */ + values(): Collection + + + /** + * Gets element with the specified key. + * @param key The key of the element to get. + */ + get(key: TKey): TValue + + + /** + * Sets the element with the specified key. + * @param key The key of the element to set. + * @param value The object to use as the value of the element to set. + */ + set(key: TKey, value: TValue): void + + + /** + * Gets the value associated with the specified key. + * @param key The key whose value to get. + * @param callback When this method returns, callback method is called with the value + * associated with the specified key, if the key is found; otherwise, null for the type of the value parameter. + */ + tryGetValue(key: TKey, callback: (value: TValue) => void): boolean + + + /** + * Removes the element with the specified key from the Dictionary. + * @param key The key of the element to remove. + */ + remove(key: TKey): boolean + } + interface DictionaryConstructor { + + /** + * Initializes a new instance of the Dictionary class that is empty, + */ + new (): Dictionary + + + /** + * Initializes a new instance of the Dictionary class that contains elements copied + * from the specified Dictionary and uses the default equality comparer for the key type. + * @param dictionary The Dictionary whose elements are copied to the new Dictionary. + */ + new (dictionary: Dictionary): Dictionary + + + /** + * Initializes a new instance of the Dictionary class that is empty, and uses the specified EqualityComparer. + * @param comparer The EqualityComparer implementation to use when comparing keys. + */ + new (comparer: EqualityComparer): Dictionary + + + /** + * Initializes a new instance of the Dictionary class that is empty, has the specified initial capacity, and uses the default equality comparer for the key type. + * @param capacity The initial number of elements that the Dictionary can contain. + */ + new (capacity: number): Dictionary + + + /** + * Initializes a new instance of the Dictionary that is empty, has the specified initial capacity, and uses the specified EqualityComparer. + * @param capacity The initial number of elements that the Dictionary can contain. + * @param comparer The EqualityComparer implementation to use when comparing keys. + */ + new (capacity: number, comparer: EqualityComparer): Dictionary + + + /** + * Initializes a new instance of the Dictionary class that contains elements copied + * from the specified Dictionary and uses the specified EqualityComparer. + * @param dictionary The Dictionary whose elements are copied to the new Dictionary. + * @param comparer The EqualityComparer implementation to use when comparing keys. + */ + new (dictionary: Dictionary, comparer: EqualityComparer): Dictionary + } + + + + /** + * Represents a set of values. + */ + interface HashSet extends Collection { + + /** + * Adds an element to the current set. + * @param item The element to add to the set. + */ + add(item: T): boolean + + + /** + * Removes all elements from a HashSet object. + */ + clear(): void + + + /** + * Copies the elements of a HashSet object to an array. + * @param array The one-dimensional array that is the destination of the elements copied from the HashSet object. + */ + copyTo(array: T[]): void + + + /** + * Copies the elements of a HashSet object to an array. starting at the specified array index. + * @param array The one-dimensional array that is the destination of the elements copied from the HashSet object. + * @param arrayIndex The zero-based index in array at which copying begins. + */ + copyTo(array: T[], arrayIndex: number): void + + + /** + * Copies the elements of a HashSet object to an array. + * @param array The one-dimensional array that is the destination of the elements copied from the HashSet object. + * @param arrayIndex The zero-based index in array at which copying begins. + * @param count The number of elements to copy to array. + */ + copyTo(array: T[], arrayIndex: number, count: number): void + + + /** + * Gets the EqualityComparer object that is used to determine equality for the values in the set. + */ + comparer(): EqualityComparer + + + /** + * Removes the specified element from a HashSet object. + * @param item The element to remove. + */ + remove(item: T): boolean + + + /** + * Removes all elements that match the conditions defined by the specified predicate from a HashSet collection. + * @param match The predicate function that defines the conditions of the elements to remove. + */ + removeWhere(match: (item: T) => boolean): number + + + /** + * Removes all elements in the specified collection from the current set. + * @param other The collection of items to remove from the set. + */ + exceptWith(other: Iterable): void + + + /** + * Modifies the current set so that it contains only elements that are also in a specified collection. + * @param other The collection to compare to the current set. + */ + intersectWith(other: Iterable): void + + + /** + * Determines whether the current set is a proper (strict) subset of a specified collection. + * @param other The collection to compare to the current set. + */ + isProperSubsetOf(other: Iterable): boolean + + + /** + * Determines whether the current set is a proper (strict) superset of a specified collection. + * @param other The collection to compare to the current set. + */ + isProperSupersetOf(other: Iterable): boolean + + + /** + * Determines whether a set is a subset of a specified collection. + * @param other The collection to compare to the current set. + */ + isSubsetOf(other: Iterable): boolean + + + /** + * Determines whether the current set is a superset of a specified collection. + * @param other The collection to compare to the current set. + */ + isSupersetOf(other: Iterable): boolean + + + /** + * Determines whether the current set overlaps with the specified collection. + * @param other The collection to compare to the current set. + */ + overlaps(other: Iterable): boolean + + + /** + * Determines whether the current set and the specified collection contain the same elements. + * @param other The collection to compare to the current set. + */ + setEquals(other: Iterable): boolean + + + /** + * Modifies the current set so that it contains only elements that are present + * either in the current set or in the specified collection, but not both. + * @param other The collection to compare to the current set. + */ + symmetricExceptWith(other: Iterable): void + + + /** + * Modifies the current set so that it contains all elements that are present + * in either the current set or the specified collection. + * @param other The collection to compare to the current set. + */ + unionWith(other: Iterable): void + + } + interface HashSetConstructor { + + /** + * Initializes a new instance of the HashSet class that is empty and uses the default equality comparer for the set type. + */ + new (): HashSet + + + /** + * Initializes a new instance of the HashSet class that uses the default equality comparer for the set type, + * and contains elements copied from the specified collection. + * @param collection The collection whose elements are copied to the new set. + */ + new (collection: Iterable): HashSet + + + /** + * Initializes a new instance of the HashSet class that is empty and uses the specified equality comparer for the set type. + * @param comparer The EqualityComparer implementation to use when comparing values in the set. + */ + new (comparer: EqualityComparer): HashSet + + + /** + * Initializes a new instance of the HashSet class that uses the specified equality comparer for the set type, + * contains elements copied from the specified collection, and uses the specified equality comparer for the set type. + * @param collection The collection whose elements are copied to the new set. + * @param comparer The EqualityComparer implementation to use when comparing values in the set. + */ + new (collection: Iterable, comparer: EqualityComparer): HashSet + } + + + + /** + * Represents a node in a LinkedList. + */ + interface LinkedListNode { + + /** + * Gets the value contained in the node. + */ + value(): T + + + /** + * Gets the LinkedList that the LinkedListNode belongs to. + */ + list(): LinkedList + + + /** + * Gets the next node in the LinkedList. + */ + next(): LinkedListNode + + + /** + * Gets the previous node in the LinkedList. + */ + previous(): LinkedListNode + } + interface LinkedListNodeConstructor { + + /** + * Initializes a new instance of the LinkedListNode class, containing the specified value. + * @param value The value to contain in the LinkedListNode + */ + new (value: T): LinkedListNode + } + + + + /** + * Represents a doubly linked list. + */ + interface LinkedList extends Collection { + + /** + * Adds an item to the LinkedList. + * @param item The object to add to the LinkedList. + */ + add(item: T): void + + + /** + * Removes all nodes from the LinkedList. + */ + clear(): void + + + /** + * Determines whether a value is in the LinkedList. + * @param value The value to locate in the LinkedList. The value can be null for reference types. + */ + contains(item: T): boolean + + + /** + * Gets the first node of the LinkedList. + */ + getFirst(): LinkedListNode + + + /** + * Gets the last node of the LinkedList. + */ + getLast(): LinkedListNode + + + /** + * Adds the specified new node after the specified existing node in the LinkedList and returns the new LinkedListNode. + * @param node The LinkedListNode after which to insert newNode. + * @param newNode The new LinkedListNode to add to the LinkedList. + */ + addAfter(node: LinkedListNode, newNode: LinkedListNode): LinkedListNode + + + /** + * Adds the specified new node after the specified existing node in the LinkedList. + * returns The new LinkedListNode containing value. + * @param node The LinkedListNode after which to insert newNode. + * @param value The value to add to the LinkedList. + */ + addAfter(node: LinkedListNode, value: T): LinkedListNode + + + /** + * Adds the specified new node before the specified existing node in the LinkedList. + * returns The new LinkedListNode. + * @param node The LinkedListNode before which to insert newNode. + * @param newNode The new LinkedListNode to add to the LinkedList. + */ + addBefore(node: LinkedListNode, newNode: LinkedListNode): LinkedListNode + + + /** + * Adds the specified new node before the specified existing node in the LinkedList. + * returns The new LinkedListNode containing value. + * @param node The LinkedListNode before which to insert newNode. + * @param value The value to add to the LinkedList. + */ + addBefore(node: LinkedListNode, value: T): LinkedListNode + + + /** + * Adds the specified new node at the start of the LinkedList. + * returns The new LinkedListNode. + * @param node The new LinkedListNode to add at the start of the LinkedList. + */ + addFirst(node: LinkedListNode): LinkedListNode + + + /** + * Adds the specified new node at the start of the LinkedList. + * returns The new LinkedListNode containing value. + * @param value The value to add at the start of the LinkedList. + */ + addFirst(value: T): LinkedListNode + + + /** + * Adds the specified new node at the end of the LinkedList. + * returns The new LinkedListNode. + * @param node The new LinkedListNode to add at the end of the LinkedList. + */ + addLast(node: LinkedListNode): LinkedListNode + + + /** + * Adds the specified new node at the end of the LinkedList. + * returns The new LinkedListNode containing value. + * @param value The value to add at the end of the LinkedList. + */ + addLast(value: T): LinkedListNode + + + /** + * Finds the first node that contains the specified value. + * @param value The value to locate in the LinkedList. + */ + find(value: T): LinkedListNode + + + /** + * Finds the last node that contains the specified value. + * @param value The value to locate in the LinkedList. + */ + findLast(value: T): LinkedListNode + + /** + * Removes the node at the start of the LinkedList. + * returns true if the node is successfully removed; otherwise, false. + * This method also returns false if value was not found in the original LinkedList. + * @param node + */ + remove(node: LinkedListNode): boolean + + + /** + * Removes the first occurrence of the specified value from the LinkedList. + * returns true if the element containing value is successfully removed; otherwise, false. + * This method also returns false if value was not found in the original LinkedList. + * @param value The value to remove from the LinkedList. + */ + remove(value: T): boolean + + + /** + * Removes the node at the start of the LinkedList. + */ + removeFirst(): void + + + /** + * Removes the node at the end of the LinkedList. + */ + removeLast(): void + } + interface LinkedListConstructor { + + /** + * Initializes a new instance of the LinkedList class that is empty. + */ + new (): LinkedList + + + /** + * Initializes a new instance of the LinkedList class that contains elements copied from the specified Enumerable. + * @param collection The collection to copy elements from. + */ + new (collection: Iterable): LinkedList + } + + + + /** + * Represents a first-in, first-out collection of objects. + */ + interface Queue extends Collection { + + /** + * Removes all objects from the Queue. + */ + clear(): void + + + /** + * Determines whether an element is in the Queue. + * @param item The object to locate in the Queue. + */ + contains(item: T): boolean + + + /** + * Removes and returns the object at the beginning of the Queue. + */ + dequeue(): T + + /** + * Adds an object to the end of the Queue. + * @param item The object to add to the Queue. + */ + enqueue(item: T): void + + + /** + * Returns the object at the beginning of the Queue without removing it. + */ + peek(): T + + + /** + * Copies the Queue to a new array. + */ + toArray(): T[] + } + interface QueueConstructor { + + /** + * Initializes a new instance of the Queue class that is empty. + */ + new (): Queue + + + /** + * Initializes a new instance of the Queue class that contains elements copied from the specified collection. + * @param collection The collection to copy elements from. + */ + new (collection: Iterable): Queue + } + + + + /** + * Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type. + */ + interface Stack extends Collection { + + /** + * Removes all objects from the Stack. + */ + clear(): void + + + /** + * Determines whether an element is in the Stack. + * @param item The object to locate in the Stack. + */ + contains(item: T): boolean + + + /** + * Returns the object at the top of the Stack without removing it. + */ + peek(): T + + + /** + * Removes and returns the object at the top of the Stack. + */ + pop(): T + + + /** + * Inserts an object at the top of the Stack. + * @param item The object to push onto the Stack. + */ + push(item: T): void + + + /** + * Copies the Stack to a new array. + */ + toArray(): T[] + } + interface StackConstructor { + + /** + * Initializes a new instance of the Stack class that is empty. + */ + new (): Stack + + + /** + * Initializes a new instance of the Stack class that contains elements copied from the specified collection. + * @param collection The collection to copy elements from. + */ + new (collection: Iterable): Stack + } + + + + /** + * Defines a data structures that map keys to Enumerable sequences of values. + */ + interface Lookup extends Collection> { + + /** + * Determines whether a specified key exists in the Lookup. + * @param key The key to search for in the Lookup. + */ + contains(key: TKey): boolean + contains(item: Grouping): boolean + + + + /** + * Gets the value associated with the specified key. + * @param key The key of the element to add. + */ + get(key: TKey): Enumerable + } + + + + /** + * Represents a collection of objects that have a common key. + */ + interface Grouping extends Collection { + + /** + * Gets the key of the Grouping. + */ + key: TKey + } + + + + /** + * Exposes the enumerator, which supports a simple iteration over a collection of a specified type. + */ + interface OrderedEnumerable extends Enumerable { + + /** + * Performs a subsequent ordering on the elements of an OrderedEnumerable according to a key. + * @param keySelector The selector used to extract the key for each element. + * @param comparer The Comparer used to compare keys for placement in the returned sequence. + * @param descending true to sort the elements in descending order; false to sort the elements in ascending order. + */ + createOrderedEnumerable(keySelector: (item: TElement) => TKey, comparer: Comparer, descending: boolean): OrderedEnumerable + + + /** + * Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. + * Returns an OrderedEnumerable whose elements are sorted in descending order according to a key. + * @param keySelector A function to extract a key from each element. + */ + thenBy(keySelector: (item: TElement) => TKey): OrderedEnumerable + + + /** + * Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparer. + * Returns an OrderedEnumerable whose elements are sorted according to a key. + * @param keySelector A function to extract a key from each element. + * @param comparer A Comparer to compare keys. + */ + thenBy(keySelector: (item: TElement) => TKey, comparer: Comparer): OrderedEnumerable + + + /** + * Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. + * Returns an OrderedEnumerable whose elements are sorted in descending order according to a key. + * @param keySelector A function to extract a key from each element. + */ + thenByDescending(keySelector: (item: TElement) => TKey): OrderedEnumerable + + + /** + * Performs a subsequent ordering of the elements in a sequence in descending order, according to a key. + * Returns an OrderedEnumerable whose elements are sorted in descending order according to a key. + * @param keySelector A function to extract a key from each element. + * @param comparer A Comparer to compare keys. + */ + thenByDescending(keySelector: (item: TElement) => TKey, comparer: Comparer): OrderedEnumerable + } + + + + /** + * Defines Enumerable extention methods applied on Enumerable + */ + interface Enumerable { + + + /** + * Applies an accumulator function over a sequence. + * Returns the final accumulator value. + * @param func An accumulator function to be invoked on each element. + */ + aggregate(func: (accumulate: T, item: T) => T): T + + + /** + * Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value. + * Returns the final accumulator value. + * @param seed The initial accumulator value. + * @param func An accumulator function to be invoked on each element. + */ + aggregate(seed: TAccumulate, func: (accumulate: TAccumulate, item: T) => TAccumulate): TAccumulate + + + /** + * Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value, + * and the specified function is used to select the result value. + * Returns the final accumulator value. + * @param seed The initial accumulator value. + * @param func An accumulator function to be invoked on each element. + * @param resultSelector A function to transform the final accumulator value into the result value. + */ + aggregate(seed: TAccumulate, func: (accumulate: TAccumulate, item: T) => TAccumulate, resultSelector: (accumulate: TAccumulate) => TResult): TResult; + + + /** + * Determines whether all elements of a sequence satisfy a condition. + * Returns true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false. + * @param predicate A function to test each element for a condition. + */ + all(predicate: (item: T) => boolean): boolean + + + /** + * Determines whether a sequence contains any elements. + * Returns true if the source sequence contains any elements; otherwise, false. + */ + any(): boolean + + + /** + * Determines whether any element of a sequence satisfies a condition. + * Returns true if any elements in the source sequence pass the test in the specified predicate; otherwise, false. + * @param predicate A function to test each element for a condition. + */ + any(predicate: (item: T) => boolean): boolean + + + /** + * Returns the input typed as Enumerable. + */ + asEnumerable(): Enumerable + + + /** + * Computes the average of a sequence of numeric values. + */ + average(): number + + + /** + * Computes the average of a sequence of numeric values that are obtained by invoking a transform function on each element of the input sequence. + * @param selector A transform function to apply to each element. + */ + average(selector: (item: number) => number): number + + + /** + * Concatenates two sequences. + * @param second The sequence to concatenate to the first sequence. + */ + concat(second: Iterable): Enumerable + + + /** + * Determines whether a sequence contains a specified element by using the default equality comparer. + * @param value The value to locate in the sequence. + */ + contains(value: T): boolean + + + /** + * Returns the last element of a sequence that satisfies a specified condition. + * @param value The value to locate in the sequence. + * @param comparer An equality comparer to compare values. + */ + contains(value: T, comparer: EqualityComparer): boolean + + + /** + * Returns the number of elements in a sequence. + */ + count(): number + + + /** + * Returns a number that represents how many elements in the specified sequence satisfy a condition. + * @param predicate A function to test each element for a condition. + */ + count(predicate: (item: T) => boolean): number + + + /** + * Returns the elements of the specified sequence or null if the sequence is empty. + */ + defaultIfEmpty(): Enumerable + + + /** + * Returns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty. + * @param defaultValue The value to return if the sequence is empty. + */ + defaultIfEmpty(defaultValue: T): Enumerable + + + /** + * Returns distinct elements from a sequence by using the default equality comparer to compare values. + */ + distinct(): Enumerable + + + /** + * Produces the set difference of two sequences by using the EqualityComparer to compare values. + * @param comparer An EqualityComparer to compare values. + */ + distinct(comparer: EqualityComparer): Enumerable + + + /** + * Produces the set difference of two sequences by using the default equality comparer to compare values. + * @param second An Iterable whose elements that also occur in the first sequence will cause those elements to be removed from the returned sequence. + */ + except(second: Iterable): Enumerable + + + /** + * Produces the set difference of two sequences by using the specified EqualityComparer to compare values. + * @param second An Iterable whose elements that also occur in the first sequence will cause those elements to be removed from the returned sequence. + * @param comparer An EqualityComparer to compare values. + */ + except(second: Iterable, comparer: EqualityComparer): Enumerable + + + /** + * Returns the element at a specified index in a sequence. Throws an error if the index is less than 0 or greater than or equal to the number of elements in source. + * @param index The zero-based index of the element to retrieve. + */ + elementAt(index: number): T + + + /** + * Returns the first element of a sequence. this method throws an exception if there is no element in the sequence. + */ + first(): T + + + /** + * Returns the first element in a sequence that satisfies a specified condition. this method throws an exception if there is no element in the sequence. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + */ + first(predicate: (item: T) => boolean): T + + + /** + * Returns the first element of a sequence, or null if the sequence contains no elements. + */ + firstOrDefault(): T + + + /** + * Returns the first element of the sequence that satisfies a condition or null if no such element is found. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + */ + firstOrDefault(predicate: (item: T) => boolean): T + + + /** + * Returns the first element of the sequence that satisfies a condition or a default value if no such element is found. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + * @param defaultValue The value to return if no element exists with specified condition. + */ + firstOrDefault(predicate: (item: T) => boolean, defaultValue: T): T + + + /** + * Performs the specified action on each element of an Enumerable. + * @param action The action function to perform on each element of an Enumerable. + */ + forEach(action: (item: T) => void): void + + + /** + * Performs the specified action on each element of an Enumerable. + * @param action The action function to perform on each element of an Enumerable; the second parameter of the function represents the index of the source element. + */ + forEach(action: (item: T, index: number) => void): void + + + /** + * Groups the elements of a sequence according to a specified key selector function. + * @param keySelector A function to extract the key for each element. + */ + groupBy(keySelector: (item: T) => TKey): Enumerable>; + + + /** + * Groups the elements of a sequence according to a specified key selector function. + * @param keySelector A function to extract the key for each element. + * @param comparer An equality comparer to compare values. + */ + groupBy(keySelector: (item: T) => TKey, comparer: EqualityComparer): Enumerable>; + + + /** + * Groups the elements of a sequence according to a specified key selector function and projects the elements for each group by using a specified function. + * @param keySelector A function to extract the key for each element. + * @param elementSelector A function to map each source element to an element in the Grouping. + */ + groupBy(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement): Enumerable>; + + + /** + * Groups the elements of a sequence according to a key selector function. + * The keys are compared by using a comparer and each group's elements are projected by using a specified function. + * @param keySelector A function to extract the key for each element. + * @param elementSelector A function to map each source element to an element in the Grouping. + * @param comparer An equality comparer to compare values. + */ + groupBy(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement, comparer: EqualityComparer): Enumerable>; + + + /** + * Groups the elements of a sequence according to a specified key selector function and projects the elements for each group by using a specified function. + * @param keySelector A function to extract the key for each element. + * @param elementSelector A function to map each source element to an element in the Grouping. + * @param resultSelector A function to extract the key for each element. + */ + groupBy(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement, resultSelector: (key: TKey, elements: Iterable) => TResult): Enumerable; + + + /** + * Groups the elements of a sequence according to a key selector function. + * The keys are compared by using a comparer and each group's elements are projected by using a specified function. + * @param keySelector A function to extract the key for each element. + * @param elementSelector A function to map each source element to an element in the Grouping. + * @param resultSelector A function to extract the key for each element. + * @param comparer An equality comparer to compare values. + */ + groupBy(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement, resultSelector: (key: TKey, elements: Iterable) => TResult, comparer: EqualityComparer): Enumerable; + + + /** + * Correlates the elements of two sequences based on equality of keys and groups the results. The default equality comparer is used to compare keys. + * @param inner The sequence to join to the current sequence. + * @param outerKeySelector A function to extract the join key from each element of the first sequence. + * @param innerKeySelector A function to extract the join key from each element of the second sequence. + * @param resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + */ + groupJoin(inner: Iterable, outerKeySelector: (item: T) => TKey, innerKeySelector: (item: TInner) => TKey, resultSelector: (outer: T, inner: Enumerable) => TResult): Enumerable; + + + /** + * Correlates the elements of two sequences based on key equality and groups the results. A specified EqualityComparer is used to compare keys. + * @param inner The sequence to join to the current sequence. + * @param outerKeySelector A function to extract the join key from each element of the first sequence. + * @param innerKeySelector A function to extract the join key from each element of the second sequence. + * @param resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + * @param comparer An equality comparer to compare values. + */ + groupJoin(inner: Iterable, outerKeySelector: (item: T) => TKey, innerKeySelector: (item: TInner) => TKey, resultSelector: (outer: T, inner: Enumerable) => TResult, comparer: EqualityComparer): Enumerable; + + + /** + * Produces the set intersection of two sequences by using the default equality comparer to compare values. + * @param second An Iterable whose distinct elements that also appear in the first sequence will be returned. + */ + intersect(second: Iterable): Enumerable; + + + /** + * Produces the set intersection of two sequences by using the default equality comparer to compare values. + * @param second An Iterable whose distinct elements that also appear in the first sequence will be returned. + * @param comparer An EqualityComparer to compare values. + */ + intersect(second: Iterable, comparer: EqualityComparer): Enumerable; + + + /** + * Correlates the elements of two sequences based on matching keys. The default equality comparer is used to compare keys. + * @param inner The sequence to join to the current sequence. + * @param outerKeySelector A function to extract the join key from each element of the first sequence. + * @param innerKeySelector A function to extract the join key from each element of the second sequence. + * @param resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + */ + join(inner: Iterable, outerKeySelector: (item: T) => TKey, innerKeySelector: (item: TInner) => TKey, resultSelector: (outer: T, inner: TInner) => TResult): Enumerable; + + + /** + * Correlates the elements of two sequences based on matching keys. A specified EqualityComparer is used to compare keys. + * @param inner The sequence to join to the current sequence. + * @param outerKeySelector A function to extract the join key from each element of the first sequence. + * @param innerKeySelector A function to extract the join key from each element of the second sequence. + * @param resultSelector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence. + * @param comparer An equality comparer to compare values. + */ + join(inner: Iterable, outerKeySelector: (item: T) => TKey, innerKeySelector: (item: TInner) => TKey, resultSelector: (outer: T, inner: TInner) => TResult, comparer: EqualityComparer): Enumerable; + + + /** + * Returns the last element of a sequence. + */ + last(): T + + + /** + * Returns the last element of a sequence that satisfies a specified condition. + * @param predicate A function to test each source element for a condition. + */ + last(predicate: (item: T) => boolean): T + + + /** + * Returns the first element of a sequence, or null if the sequence contains no elements. + */ + lastOrDefault(): T + + + /** + * Returns the last element of a sequence, or null if the sequence contains no elements. + * @param predicate A function to test each source element for a condition. + */ + lastOrDefault(predicate: (item: T) => boolean): T + + + /** + * Returns the last element of a sequence that satisfies a condition or null if no such element is found. + * @param predicate A function to test each source element for a condition. + * @param defaultValue The value to return if no element exists with specified condition. + */ + lastOrDefault(predicate: (item: T) => boolean, defaultValue: T): T + + + /** + * Returns the maximum value in a sequence of values. + */ + max(): T + + + /** + * Invokes a transform function on each element of a sequence and returns the maximum value. + * @param selector A transform function to apply to each element. + */ + max(selector: (item: T) => TResult): TResult + + + /** + * Returns the minimum value in a sequence of values. + */ + min(): T + + + /** + * Invokes a transform function on each element of a sequence and returns the minimum value. + * @param selector A transform function to apply to each element. + */ + min(selector: (item: T) => TResult): TResult + + + /** + * Filters the elements of an Enumerable based on a specified type. + * @param type The type to filter the elements of the sequence on. + */ + ofType(type: { new (...args: any[]): TResult }): Enumerable + + + /** + * Sorts the elements of a sequence in ascending order by using a specified comparer. + * @param keySelector A function to extract a key from each element. + */ + orderBy(keySelector: (item: T) => TKey): OrderedEnumerable + + + /** + * Sorts the elements of a sequence in ascending order by using a specified comparer. + * Returns an OrderedEnumerable whose elements are sorted according to a key. + * @param keySelector A function to extract a key from each element. + * @param comparer A Comparer to compare keys. + */ + orderBy(keySelector: (item: T) => TKey, comparer: EqualityComparer): OrderedEnumerable + + + /** + * Sorts the elements of a sequence in descending order by using a specified comparer. + * Returns an OrderedEnumerable whose elements are sorted according to a key. + * Returns an OrderedEnumerable whose elements are sorted in descending order according to a key. + * @param keySelector A function to extract a key from each element. + */ + orderByDescending(keySelector: (item: T) => TKey): OrderedEnumerable + + + /** + * Sorts the elements of a sequence in descending order by using a specified comparer. + * Returns an OrderedEnumerable whose elements are sorted in descending order according to a key. + * @param keySelector A function to extract a key from each element. + * @param comparer A Comparer to compare keys. + */ + orderByDescending(keySelector: (item: T) => TKey, comparer: EqualityComparer): OrderedEnumerable + + + /** + * Inverts the order of the elements in a sequence. + */ + reverse(): Enumerable + + + /** + * Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type. + * @param second An Iterable to compare to the first sequence. + */ + sequenceEqual(second: Iterable): boolean + + + /** + * Determines whether two sequences are equal by comparing their elements by using a specified EqualityComparer. + * @param second An Iterable to compare to the first sequence. + * @param comparer The EqualityComparer to compare values. + */ + sequenceEqual(second: Iterable, comparer: EqualityComparer): boolean + + + /** + * Projects each element of a sequence into a new form. + * @param selector A transform function to apply to each source element. + */ + select(selector: (item: T) => TResult): Enumerable + + + /** + * Projects each element of a sequence into a new form by incorporating the element's index. + * @param selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + */ + select(selector: (item: T, index: number) => TResult): Enumerable + + + /** + * Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence. + * @param collectionSelector A transform function to apply to each source element. + */ + selectMany(selector: (item: T) => Iterable): Enumerable; + + + /** + * Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence. The index of each source element is used in the projected form of that element. + * @param collectionSelector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + */ + selectMany(selector: (item: T, index: number) => Iterable): Enumerable; + + + /** + * Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence. + * @param collectionSelector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + * @param resultSelector A transform function to apply to each element of the intermediate sequence. + */ + selectMany(collectionSelector: (item: T) => Iterable, resultSelector: (item: T, collection: TCollection) => TResult): Enumerable; + + + /** + * Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence. The index of each source element is used in the projected form of that element. + * @param collectionSelector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + * @param resultSelector A transform function to apply to each element of the intermediate sequence. + */ + selectMany(collectionSelector: (item: T, index: number) => Iterable, resultSelector: (item: T, collection: TCollection) => TResult): Enumerable; + + + /** + * Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence. + */ + single(): T + + + /** + * Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists. + * @param predicate A function to test each source element for a condition. + */ + single(predicate: (item: T) => boolean): T + + + /** + * Returns the only element of a sequence, or a null if the sequence is empty; this method throws an exception if there is more than one element in the sequence. + */ + singleOrDefault(): T + + + /** + * Returns the only element of a sequence that satisfies a specified condition or a null if no such element exists; this method throws an exception if more than one element satisfies the condition. + * @param predicate A function to test each source element for a condition. + */ + singleOrDefault(predicate: (item: T) => boolean): T + + + /** + * Returns the only element of a sequence that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. + * @param predicate A function to test each source element for a condition. + * @param defaultValue The value to return if no element exists with specified condition. + */ + singleOrDefault(predicate: (item: T) => boolean, defaultValue: T): T + + + /** + * Bypasses a specified number of elements in a sequence and then returns the remaining elements. + * @param count The number of elements to skip before returning the remaining elements. + */ + skip(count: number): Enumerable + + + /** + * Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. + * @param predicate A function to test each source element for a condition. + */ + skipWhile(predicate: (item: T) => boolean): Enumerable + + + /** + * Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + */ + skipWhile(predicate: (item: T, index: number) => boolean): Enumerable + + + /** + * Computes the sum of a sequence of values. + */ + sum(): number + + + /** + * Computes the sum of the sequence of values that are obtained by invoking a transform function on each element of the input sequence. + * @param selector A transform function to apply to each element. + */ + sum(selector: (item: T) => number): number + + + /** + * Returns a specified number of contiguous elements from the start of a sequence. + * @param count The number of elements to return. + */ + take(count: number): Enumerable + + + /** + * Returns elements from a sequence as long as a specified condition is true. + * @param predicate A function to test each source element for a condition. + */ + takeWhile(predicate: (item: T) => boolean): Enumerable + + + /** + * Returns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + */ + takeWhile(predicate: (item: T, index: number) => boolean): Enumerable + + + /** + * Creates an array from an Enumerable. + */ + toArray(): T[] + + + /** + * Creates a Dictionary from an Enumerable according to a specified key selector function. + * @param keySelector A function to extract a key from each element. + */ + toDictionary(keySelector: (item: T) => TKey): Dictionary; + + + /** + * Creates a Dictionary from an Enumerable according to specified key selector and comparer. + * @param keySelector A function to extract a key from each element. + * @param comparer An equality comparer to compare values. + */ + toDictionary(keySelector: (item: T) => TKey, comparer: EqualityComparer): Dictionary; + + + /** + * Creates a Dictionary from an Enumerable according to specified key selector and element selector functions. + * @param keySelector A function to extract a key from each element. + * @param elementSelector A transform function to produce a result element value from each element. + */ + toDictionary(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement): Dictionary; + + + /** + * Creates a Dictionary from an Enumerable according to a specified key selector function, a comparer, and an element selector function. + * @param keySelector A function to extract a key from each element. + * @param elementSelector A transform function to produce a result element value from each element. + * @param comparer An equality comparer to compare values. + */ + toDictionary(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement, comparer: EqualityComparer): Dictionary; + + + /** + * Creates a List from an Enumerable. + */ + toList(): List + + + /** + * Creates a Lookup from an Enumerable according to a specified key selector function. + * @param keySelector A function to extract a key from each element. + */ + toLookup(keySelector: (item: T) => TKey): Lookup; + + + /** + * Creates a Lookup from an Enumerable according to a specified key selector function and comparer. + * @param keySelector A function to extract a key from each element. + * @param comparer An equality comparer to compare values. + */ + toLookup(keySelector: (item: T) => TKey, comparer: EqualityComparer): Lookup; + + + /** + * Creates a Lookup from an Enumerable according to specified key selector and element selector functions. + * @param keySelector A function to extract a key from each element. + * @param elementSelector A transform function to produce a result element value from each element. + */ + toLookup(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement): Lookup; + + + /** + * Creates a Lookup from an Enumerable according to a specified key selector function, a comparer and an element selector function. + * @param keySelector A function to extract a key from each element. + * @param elementSelector A transform function to produce a result element value from each element. + * @param comparer An equality comparer to compare values. + */ + toLookup(keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement, comparer: EqualityComparer): Lookup; + + + /** + * Produces the set union of two sequences by using the default equality comparer. + * @param second An Iterable whose distinct elements form the second set for the union. + */ + union(second: Iterable): Enumerable + + + /** + * Produces the set union of two sequences by using a specified EqualityComparer. + * @param second An Iterable whose distinct elements form the second set for the union. + * @param comparer The EqualityComparer to compare values. + */ + union(second: Iterable, comparer: EqualityComparer): Enumerable + + + /** + * Filters a sequence of values based on a predicate. + * @param predicate A function to test each source element for a condition. + */ + where(predicate: (item: T) => boolean): Enumerable; + + + /** + * Filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function. + * @param predicate A function to test each source element for a condition; the second parameter of the function represents the index of the source element. + */ + where(predicate: (item: T, index: number) => boolean): Enumerable; + + + /** + * Merges two sequences by using the specified predicate function. + * @param second The second sequence to merge. + * @param resultSelector A function that specifies how to merge the elements from the two sequences. + */ + zip(second: Iterable, resultSelector: (first: T, second: TSecond) => TResult): Enumerable; + } + + + + /** + * Represents Array-like objects which has the "length" property and indexed properties access, eg. jQuery + */ + interface ArrayLike { + length: number; + [n: number]: T; + } + + + + /** + * Provides 'hash' and 'equals' functions for a particular type, suitable for use in hashing algorithms and data structures such as a hash table. + */ + interface RuntimeComparer { + + /** + * Serves as a hash function for a particular type. + */ + __hash__(): number; + + /** + * Determines whether the specified Object is equal to the current Object. + */ + __equals__(obj: any): boolean; + } + + + + /** + * Provides a set of static methods that provide support for internal operations. + */ + interface MultiplexRuntime { + + /** + * Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures such as a hash table. + * @param obj An object to retrieve the hash code for. + */ + hash(obj: any): number; + + + /** + * Determines whether the specified object instances are considered equal. + * @param objA The first object to compare. + * @param objB The second object to compare. + */ + equals(objA: any, objB: any): boolean; + + + /** + * Performs a comparison of two objects of the same type and returns a value indicating whether one object is less than, equal to, or greater than the other. + * @param objA The first object to compare. + * @param objB The second object to compare. + */ + compare(objA: T, objB: T): number; + + + /** + * Creates A function expression from the specified string lambda expression + * @param exp String lambda expression. + */ + lambda(exp: string): (obj: T) => TResult; + + + /** + * Creates A function expression from the specified string lambda expression + * @param exp String lambda expression. + */ + lambda(exp: string): (obj1: T1, obj2: T2) => TResult; + + + /** + * Creates A function expression from the specified string lambda expression + * @param exp String lambda expression. + */ + lambda(exp: string): (obj1: T1, obj2: T2, obj3: T3) => TResult; + + + /** + * Creates A function expression from the specified string lambda expression + * @param exp String lambda expression. + */ + lambda(exp: string): (...args: any[]) => TResult; + + + /** + * Defines new or modifies existing properties directly on the specified object, returning the object. + * @param obj The object on which to define or modify properties. + * @param prop The name of the property to be defined or modified. + * @param attributes The descriptor for the property being defined or modified. + */ + define(obj: T, prop: String, attributes: PropertyDescriptor): T; + + + /** + * Extends the given object by implementing supplied members. + * @param obj The object on which to define or modify properties. + * @param properties Represetnts the mixin source object + * @param attributes The descriptor for the property being defined or modified. + */ + mixin(obj: T, properties: Object, attributes?: PropertyDescriptor): T; + } + + + + /** + * Defines MultiplexStatic module members + */ + interface MultiplexStatic { + + + + /* Factory Methods + --------------------------------------------------------------------------*/ + + /** + * Exposes the enumerator, which supports an iteration over the specified Enumerable object. + * @param obj An Iterable object. eg. Enumerable, Array, String, Set, Map, Iterable & Generators + */ + (obj: Iterable): Enumerable + + + /** + * Defines an enumerator, which supports an iteration over the specified Generator function. + * @param factory An Enumerator factory function. + */ + (factory: () => Enumerator): Enumerable + + + /** + * Defines an enumerator, which supports an iteration over the items of the specified Array-like object. + * An Array-like object is an object which has the "length" property and indexed properties access, eg. jQuery + * @param obj An Array-like object. + */ + (obj: ArrayLike): Enumerable + + + /** + * Defines an enumerator, which supports an iteration over the arguments local variable available within all functions. + * @param obj arguments local variable available within all functions. + */ + (obj: IArguments): Enumerable + + + /** + * Defines an enumerator, which supports an iteration over the properties of the specified object. + * @param obj A regular Object. + */ + (obj: Object): Enumerable> + + + + + + + /* Static Methods + --------------------------------------------------------------------------*/ + + /** + * Gets and combines hash code for the given parameters, calls the overridden "hash" method when available. + * @param objs Optional number of objects to combine their hash codes. + */ + hash(...obj: any[]): number; + + + /** + * Determines whether the specified object instances are considered equal. calls the overridden "equals" method when available. + * @param objA The first object to compare. + * @param objB The second object to compare. + */ + equals(objA: any, objB: any): boolean; + + + /** + * Determines whether the specified object instances are considered equal. calls the overridden "equals" method when available. + * @param objA The first object to compare. + * @param objB The second object to compare. + * @param comparer An equality comparer to compare values. + */ + equals(objA: any, objB: any, comparer: EqualityComparer): boolean; + + + /** + * Performs a comparison of two objects of the same type and returns a value indicating whether one object is less than, equal to, or greater than the other. + * @param objA The first object to compare. + * @param objB The second object to compare. + */ + compare(objA: T, objB: T): number; + + + /** + * Extends Enumerable extension methods to the given type + * @param type The type to extend. + */ + enumerableExtend(type: Function): void; + + + /** + * Returns an empty Enumerable. + */ + empty(): Enumerable; + + + /** + * Detects if an object is Enumerable. + * @param obj An object to check its Enumerability. + */ + is(obj: any): boolean; + + + /** + * Generates a sequence of integral numbers within a specified range. + * @param start The value of the first integer in the sequence. + * @param count The number of sequential integers to generate. + */ + range(start: number, count: number): Enumerable; + + + /** + * Generates a sequence that contains one repeated value. + * @param element The value to be repeated. + * @param count The number of times to repeat the value in the generated sequence. + */ + repeat(element: T, count: number): Enumerable; + + + + + + + /* Mutiplex Types + --------------------------------------------------------------------------*/ + + /** + * Provides a set of static methods that provide support for internal operations. + */ + runtime: MultiplexRuntime + + /** + * Supports a simple iteration over a collection. + */ + Enumerator: EnumeratorConstructor + + /** + * Exposes the enumerator, which supports a simple iteration over a collection of a specified type. + */ + Enumerable: EnumerableConstructor + + /** + * Provides a base class for implementations of Comparer generic interface. + */ + Comparer: ComparerConstructor + + /** + * Provides a base class for implementations of the EqualityComparer. + */ + EqualityComparer: EqualityComparerConstructor + + /** + * Initializes a new instance of the abstract Collection class. + */ + Collection: CollectionConstructor + + /** + * Initializes a new instance of the abstract Collection class. + */ + ReadOnlyCollection: ReadOnlyCollectionConstructor + + /** + * Represents a strongly typed list of objects that can be accessed by index. + */ + List: ListConstructor + + /** + * Represents a collection of key/value pairs that are sorted by key based on the associated Comparer implementation. + */ + SortedList: SortedListConstructor + + /** + * Defines a key/value pair that can be set or retrieved. + */ + KeyValuePair: KeyValuePairConstructor + + /** + * Represents a collection of keys and values. + */ + Dictionary: DictionaryConstructor + + /** + * Represents a set of values. + */ + HashSet: HashSetConstructor + + /** + * Represents a node in a LinkedList. + */ + LinkedListNode: LinkedListNodeConstructor + + /** + * Represents a doubly linked list. + */ + LinkedList: LinkedListConstructor + + /** + * Represents a first-in, first-out collection of objects. + */ + Queue: QueueConstructor + + /** + * Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type. + */ + Stack: StackConstructor + } +} \ No newline at end of file