Skip to content

Commit

Permalink
Improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
emonkak committed Oct 10, 2016
1 parent 48f366d commit 2643803
Show file tree
Hide file tree
Showing 27 changed files with 319 additions and 212 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@
"extension": [
".ts"
],
"include": [
"src"
],
"exclude": [
"dist",
"node_modules",
"test",
"typings"
],
"require": [
Expand Down
8 changes: 5 additions & 3 deletions src/internal/OrderedEnumerable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ export default class OrderedEnumerable<TElement, TKey> extends Enumerable<TEleme
return this;
}

[Symbol.iterator](): Iterator<TElement> {
return this.toArray()[Symbol.iterator]();
*[Symbol.iterator](): Iterator<TElement> {
for (const element of this.toArray()) {
yield element;
}
}

thenBy<TKey>(keySelector?: (value: TElement) => TKey): OrderedEnumerable<TElement, TKey> {
Expand Down Expand Up @@ -262,7 +264,7 @@ export default class OrderedEnumerable<TElement, TKey> extends Enumerable<TEleme
return current;
}

lastInPartitionOrDefault(minIndex: number, maxIndex: number, defaultValue: TElement = null): TElement {
lastOrDefaultInPartition(minIndex: number, maxIndex: number, defaultValue: TElement = null): TElement {
const array = Array.from(this._source);
const count = array.length;
const comparer = this._getComparer();
Expand Down
4 changes: 2 additions & 2 deletions src/internal/OrderedPartition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class OrderedPartition<TElement> extends Partition<TElement> {

take(count: number): Partition<TElement> {
let maxIndex = this._minIndex + count - 1;
if (maxIndex >= this._maxIndex) maxIndex = this._maxIndex;
if (maxIndex > this._maxIndex) maxIndex = this._maxIndex;
return new OrderedPartition(this._source, this._minIndex, maxIndex);
}

Expand All @@ -40,7 +40,7 @@ export default class OrderedPartition<TElement> extends Partition<TElement> {
}

lastOrDefault(defaultValue: TElement = null): TElement {
return this._source.lastInPartitionOrDefault(this._minIndex, this._maxIndex, defaultValue);
return this._source.lastOrDefaultInPartition(this._minIndex, this._maxIndex, defaultValue);
}

elementAt(index: number): TElement {
Expand Down
4 changes: 0 additions & 4 deletions src/internal/RangePartition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ export default class RangePartition extends Partition<number> {
this._end = start + count;
}

get length(): number {
return this._end - this._start;
}

*[Symbol.iterator](): Iterator<number> {
let current = this._start;
let end = this._end;
Expand Down
4 changes: 0 additions & 4 deletions src/internal/RepeatPartition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ export default class RepeatPartition<TResult> extends Partition<TResult> {
super();
}

get length(): number {
return this._count;
}

*[Symbol.iterator](): Iterator<TResult> {
for (let i = this._count; i > 0; i--) {
yield this._element;
Expand Down
57 changes: 46 additions & 11 deletions src/internal/partialQuickSort.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
import pivotPosition from './pivotPosition';

export default function partialQuickSort<T>(array: Array<T>, comparer: (first: T, second: T) => number, left: number, right: number, minIndex: number, maxIndex: number): void {
if (left < right) {
const pivotIndex = left + ((right - left) >> 1);
const pivotNewIndex = pivotPosition(array, comparer, left, right, pivotIndex);

if (pivotNewIndex < left + minIndex) {
partialQuickSort(array, comparer, pivotNewIndex + 1, right, minIndex, maxIndex);
} else if (pivotNewIndex > right + maxIndex) {
partialQuickSort(array, comparer, left, pivotNewIndex - 1, minIndex, maxIndex);
do {
let i = left;
let j = right;
let x = array[i + ((j - i) >> 1)];
do {
while (i < array.length && comparer(x, array[i]) > 0) {
i++;
}

while (j >= 0 && comparer(x, array[j]) < 0) {
j--;
}

if (i > j) {
break;
}

if (i < j) {
const tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}

i++;
j--;
} while (i <= j);

if (minIndex >= i) {
left = i + 1;
} else if (maxIndex <= j) {
right = j - 1;
}

if (j - left <= right - i) {
if (left < j) {
partialQuickSort(array, comparer, left, j, minIndex, maxIndex);
}

left = i;
} else {
if (i < right) {
partialQuickSort(array, comparer, i, right, minIndex, maxIndex);
}

right = j;
}
}
} while (left < right);
}
24 changes: 0 additions & 24 deletions src/internal/pivotPosition.ts

This file was deleted.

55 changes: 44 additions & 11 deletions src/internal/quickSelect.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,51 @@
import pivotPosition from './pivotPosition';
export default function quickSelect<T>(array: Array<T>, comparer: (first: T, second: T) => number, left: number, right: number, index: number): T {
do {
let i = left;
let j = right;
let x = array[i + ((j - i) >> 1)];
do {
while (i < array.length && comparer(x, array[i]) > 0) {
i++;
}

export default function quickSelect<T>(array: Array<T>, comparer: (first: T, second: T) => number, left: number, right: number, n: number): T {
while (true) {
if (left === right) return array[left];
while (j >= 0 && comparer(x, array[j]) < 0) {
j--;
}

const pivotIndex = left + ((right - left) >> 1);
const pivotNewIndex = pivotPosition(array, comparer, left, right, pivotIndex);
if (i > j) {
break;
}

if (pivotNewIndex === n) return array[n];
if (i < j) {
const tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}

if (pivotNewIndex > n) {
right = pivotNewIndex - 1;
i++;
j--;
} while (i <= j);

if (i <= index) {
left = i + 1;
} else {
left = pivotNewIndex + 1;
right = j - 1;
}
}

if (j - left <= right - i) {
if (left < j) {
right = j;
}

left = i;
} else {
if (i < right) {
left = i;
}

right = j;
}
} while (left < right);

return array[index];
}
39 changes: 12 additions & 27 deletions src/memoize.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
export default function memoize<TSource>(this: Iterable<TSource>): Iterable<TSource> {
return new MemoizeIterator(this[Symbol.iterator]() as Iterator<TSource>);
}

class MemoizeIterator<TElement> implements Iterable<TElement> {
private _buffer: TElement[] = [];

private _bufferSize: number = 0;
let buffer: TSource[] = [];
let iterator = this[Symbol.iterator]();

private _error: any;

constructor(private _iterator: Iterator<TElement>) {
}
return {
*[Symbol.iterator]() {
yield* buffer;

*[Symbol.iterator](): Iterator<TElement> {
let index = 0;
while (true) {
if (index < this._bufferSize) {
yield this._buffer[index];
} else {
if (this._iterator != null) {
let result: IteratorResult<TElement>;
if (iterator != null) {
while (true) {
let result: IteratorResult<TSource>;
try {
result = this._iterator.next();
result = iterator.next();
} catch (e) {
this._error = e;
iterator = null;
throw e;
}
if (result.done) {
this._iterator = null;
iterator = null;
break;
}
this._bufferSize = this._buffer.push(result.value);
buffer.push(result.value);
yield result.value;
} else {
if (this._error) throw this._error;
break;
}
}
index++;
}
}
}
14 changes: 12 additions & 2 deletions src/static/repeat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import EmptyPartition from '../internal/EmptyPartition';
import { argumentOutOfRange } from '../internal/errors';
import RepeatPartition from '../internal/RepeatPartition';

export default function repeat<TSource>(element: TSource, count?: number): Iterable<TSource> {
return new RepeatPartition(element, count != null ? count : Infinity);
export default function repeat<TSource>(element: TSource, count: number = Infinity): Iterable<TSource> {
if (count < 0) {
throw argumentOutOfRange('count');
}

if (count == 0) {
return new EmptyPartition<TSource>();
}

return new RepeatPartition(element, count);
}
26 changes: 5 additions & 21 deletions test/elementAtOrDefaultTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,16 @@ describe('elementAtOrDefault()', () => {
assert.strictEqual(new Enumerable(xs).elementAtOrDefault(1), 2);
assert.strictEqual(new Enumerable(xs).elementAtOrDefault(2), 3);
assert.strictEqual(new Enumerable(xs).elementAtOrDefault(3), 4);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAtOrDefault(0), 1);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAtOrDefault(1), 2);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAtOrDefault(2), 3);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAtOrDefault(3), 4);
});

it('should returns a default value if the index is out of range', () => {
const xs = [1, 2, 3, 4];

assert.strictEqual(new Enumerable(xs).elementAtOrDefault(4, 123), 123);
assert.strictEqual(new Enumerable(xs).elementAtOrDefault(4, null), null);
assert.strictEqual(new Enumerable(xs).elementAtOrDefault(4), null);
});

it('should works with orderBy()', () => {
const xs = [3, 2, 4, 1];

assert.strictEqual(new Enumerable(xs).orderBy().elementAtOrDefault(0), 1);
assert.strictEqual(new Enumerable(xs).orderBy().elementAtOrDefault(1), 2);
assert.strictEqual(new Enumerable(xs).orderBy().elementAtOrDefault(2), 3);
assert.strictEqual(new Enumerable(xs).orderBy().elementAtOrDefault(3), 4);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).elementAtOrDefault(0), 1);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).elementAtOrDefault(1), 2);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).elementAtOrDefault(0), 3);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).elementAtOrDefault(1), 4);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).skip(1).elementAtOrDefault(0), 2);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).take(1).elementAtOrDefault(0), 3);

assert.strictEqual(new Enumerable(xs).orderBy().elementAtOrDefault(4, 123), 123);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).elementAtOrDefault(3, 123), 123);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).skip(1).elementAtOrDefault(1, 123), 123);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).take(1).elementAtOrDefault(1, 123), 123);
});
});
24 changes: 4 additions & 20 deletions test/elementAtTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,15 @@ describe('elementAt()', () => {
assert.strictEqual(new Enumerable(xs).elementAt(1), 2);
assert.strictEqual(new Enumerable(xs).elementAt(2), 3);
assert.strictEqual(new Enumerable(xs).elementAt(3), 4);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAt(0), 1);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAt(1), 2);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAt(2), 3);
assert.strictEqual(new Enumerable(xs[Symbol.iterator]()).elementAt(3), 4);
});

it('should throws the exception if index is out of range', () => {
const xs = [1, 2, 3, 4];

assert.throws(() => new Enumerable(xs).elementAt(4));
});

it('should works with orderBy()', () => {
const xs = [3, 2, 4, 1];

assert.strictEqual(new Enumerable(xs).orderBy().elementAt(0), 1);
assert.strictEqual(new Enumerable(xs).orderBy().elementAt(1), 2);
assert.strictEqual(new Enumerable(xs).orderBy().elementAt(2), 3);
assert.strictEqual(new Enumerable(xs).orderBy().elementAt(3), 4);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).elementAt(0), 1);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).elementAt(1), 2);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).elementAt(0), 3);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).elementAt(1), 4);
assert.strictEqual(new Enumerable(xs).orderBy().take(2).skip(1).elementAt(0), 2);
assert.strictEqual(new Enumerable(xs).orderBy().skip(2).take(1).elementAt(0), 3);

assert.throws(() => new Enumerable(xs).orderBy().elementAt(4));
assert.throws(() => new Enumerable(xs).orderBy().take(2).elementAt(3));
assert.throws(() => new Enumerable(xs).orderBy().take(2).skip(1).elementAt(1));
assert.throws(() => new Enumerable(xs).orderBy().skip(2).take(1).elementAt(1));
});
});
Loading

0 comments on commit 2643803

Please sign in to comment.