Skip to content

Commit

Permalink
Merge branch 'master' into fromnodestream-spec
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpodwysocki authored Nov 16, 2017
2 parents feb91bb + 4048b33 commit 5e2a1b6
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 50 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
},
"devDependencies": {
"@std/esm": "0.15.0",
"@types/node": "8.0.52",
"@types/node": "8.0.53",
"@types/tape": "4.2.31",
"chalk": "2.3.0",
"command-line-args": "4.0.7",
Expand Down
147 changes: 147 additions & 0 deletions spec/asynciterable/as-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import * as Ix from '../Ix';
import * as test from 'tape-async';
const { as } = Ix.AsyncIterable;
const { map } = Ix.asynciterable;
import { hasNext, noNext } from '../asynciterablehelpers';

test('AsyncIterable#as from non-iterable', async t => {
const xs = {};
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, xs);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from string emits the string, not chars', async t => {
const x = 'foo';
const res = as(x);
const it = res[Symbol.asyncIterator]();
await hasNext(t, it, x);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from promise list', async t => {
const xs: Iterable<Promise<number>> = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3)
];
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 1);
await hasNext(t, it, 2);
await hasNext(t, it, 3);
await noNext(t, it);
t.end();
});

async function* getData(): AsyncIterable<number> {
yield 1;
yield 2;
yield 3;
}

test('AsyncIterable#as from async generator', async t => {
const xs = getData();
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 1);
await hasNext(t, it, 2);
await hasNext(t, it, 3);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from array/iterable', async t => {
const xs = [1, 2, 3];
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 1);
await hasNext(t, it, 2);
await hasNext(t, it, 3);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from array/iterable with selector', async t => {
const xs = [1, 2, 3];
const res = map(as(xs), async (x, i) => x + i);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 1);
await hasNext(t, it, 3);
await hasNext(t, it, 5);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from async generator with selector', async t => {
const xs = getData();
const res = map(as(xs), async (x, i) => x + i);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 1);
await hasNext(t, it, 3);
await hasNext(t, it, 5);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from empty array/iterable', async t => {
const xs: number[] = [];
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from array-like', async t => {
const xs = { length: 3 };
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, undefined);
await hasNext(t, it, undefined);
await hasNext(t, it, undefined);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from array-like with selector', async t => {
const xs = { length: 3 };
const res = map(as(xs), (x, i) => i);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 0);
await hasNext(t, it, 1);
await hasNext(t, it, 2);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from promise', async t => {
const xs = Promise.resolve(42);
const res = as(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 42);
await noNext(t, it);
t.end();
});

test('AsyncIterable#as from promise with selector', async t => {
const xs = Promise.resolve(42);
const res = map(as(xs), (x, i) => x + i);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, 42);
await noNext(t, it);
t.end();
});
26 changes: 8 additions & 18 deletions spec/asynciterable/from-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,14 @@ test('AsyncIterable#from from promise with selector', async t => {
t.end();
});

test('AsyncIterable#from from non-iterable', async t => {
const xs = {};
const res = from(xs);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, xs);
await noNext(t, it);
t.end();
});

test('AsyncIterable#from from array-like with selector', async t => {
const xs = {};
const res = from(xs, (x, i) => [x, i]);

const it = res[Symbol.asyncIterator]();
await hasNext(t, it, [xs, 0]);
await noNext(t, it);
t.end();
test('AsyncIterable#from from with non-iterable throws', t => {
let error = false;
try {
from({} as any);
} catch (e) {
error = true;
}
error ? t.end() : t.fail('expected from to throw');
});

interface Observer<T> {
Expand Down
4 changes: 1 addition & 3 deletions spec/asynciterablehelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ export function testOperator<Op>(op: Op) {
test(`(proto) ${message}`, async t => await (testFn as any)(t, fnNames.map(wrapProto)));
if (pipeFns.every(xs => typeof xs === 'function')) {
test(`(pipe) ${message}`, async t => await (testFn as any)(t, pipeFns.map(wrapPipe)));
// } else {
// console.log(`AsyncIterable missing a pipe fn in [${internalNames.join(`, `)}], skipping...`);
}
};
}
Expand All @@ -64,5 +62,5 @@ function wrapPipe(fn: any) {
}

function cast(source: any): any {
return source instanceof Ix.AsyncIterable ? source : Ix.AsyncIterable.from(source);
return source instanceof Ix.AsyncIterable ? source : Ix.AsyncIterable.as(source);
}
82 changes: 82 additions & 0 deletions spec/iterable/as-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as Ix from '../Ix';
import * as test from 'tape-async';
const { as } = Ix.Iterable;
const { map } = Ix.iterable;
import { hasNext, noNext } from '../iterablehelpers';

test('Iterable#as from array/iterable', t => {
const xs = [1, 2, 3];
const res = as(xs);

const it = res[Symbol.iterator]();
hasNext(t, it, 1);
hasNext(t, it, 2);
hasNext(t, it, 3);
noNext(t, it);
t.end();
});

test('Iterable#as from array/iterable with selector', t => {
const xs = [1, 2, 3];
const res = map(as(xs), (x, i) => x + i);

const it = res[Symbol.iterator]();
hasNext(t, it, 1);
hasNext(t, it, 3);
hasNext(t, it, 5);
noNext(t, it);
t.end();
});

test('Iterable#as from empty array/iterable', t => {
const xs: number[] = [];
const res = as(xs);

const it = res[Symbol.iterator]();
noNext(t, it);
t.end();
});

test('Iterable#as from array-like', t => {
const xs = { length: 3 };
const res = as(xs);

const it = res[Symbol.iterator]();
hasNext(t, it, undefined);
hasNext(t, it, undefined);
hasNext(t, it, undefined);
noNext(t, it);
t.end();
});

test('Iterable#as from array-like with selector', t => {
const xs = { length: 3 };
const res = map(as(xs), (x, i) => i);

const it = res[Symbol.iterator]();
hasNext(t, it, 0);
hasNext(t, it, 1);
hasNext(t, it, 2);
noNext(t, it);
t.end();
});

test('Iterable#as from non-iterable', t => {
const xs = {};
const res = as(xs);

const it = res[Symbol.iterator]();
hasNext(t, it, xs);
noNext(t, it);
t.end();
});

test('Iterable#as from non-iterable with selector', t => {
const xs = {};
const res = map(as(xs), (x, i) => [x, i]);

const it = res[Symbol.iterator]();
hasNext(t, it, [xs, 0]);
noNext(t, it);
t.end();
});
26 changes: 8 additions & 18 deletions spec/iterable/from-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,12 @@ test('Iterable#from from array-like with selector', t => {
t.end();
});

test('Iterable#from from non-iterable', t => {
const xs = {};
const res = from(xs);

const it = res[Symbol.iterator]();
hasNext(t, it, xs);
noNext(t, it);
t.end();
});

test('Iterable#from from non-iterable with selector', t => {
const xs = {};
const res = from(xs, (x, i) => [x, i]);

const it = res[Symbol.iterator]();
hasNext(t, it, [xs, 0]);
noNext(t, it);
t.end();
test('Iterable#from from with non-iterable throws', t => {
let error = false;
try {
from({} as any);
} catch (e) {
error = true;
}
error ? t.end() : t.fail('expected from to throw');
});
4 changes: 1 addition & 3 deletions spec/iterablehelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export function testOperator<Op>(op: Op) {
test(`(proto) ${message}`, t => (testFn as any)(t, fnNames.map(wrapProto)));
if (pipeFns.every(xs => typeof xs === 'function')) {
test(`(pipe) ${message}`, t => (testFn as any)(t, pipeFns.map(wrapPipe)));
// } else {
// console.log(`Iterable missing a pipe fn in [${internalNames.join(`, `)}], skipping...`);
}
};
}
Expand All @@ -54,5 +52,5 @@ function wrapPipe(fn: any) {
}

function cast(source: any): any {
return source instanceof Ix.Iterable ? source : Ix.Iterable.from(source);
return source instanceof Ix.Iterable ? source : Ix.Iterable.as(source);
}
31 changes: 26 additions & 5 deletions src/asynciterable/asynciterablex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,32 @@ export abstract class AsyncIterableX<T> implements AsyncIterable<T> {
return piped(this);
}

static as(source: string): AsyncIterableX<string>;
static as<T>(source: AsyncIterableInput<T>): AsyncIterableX<T>;
static as<T>(source: T): AsyncIterableX<T>;
static as(source: any) {
/* tslint:disable */
if (typeof source === 'string') {
return new OfAsyncIterable([source]);
}
if (isIterable(source) || isAsyncIterable(source)) {
return new FromAsyncIterable(source, identityAsync);
}
if (isPromise(source)) {
return new FromPromiseIterable(source, identityAsync);
}
if (isObservable(source)) {
return new FromObservableAsyncIterable(source, identityAsync);
}
if (isArrayLike(source)) {
return new FromArrayIterable(source, identityAsync);
}
return new OfAsyncIterable([source]);
/* tslint:enable */
}

static from<TSource, TResult = TSource>(
source: AsyncIterableInput<TSource> | TSource,
source: AsyncIterableInput<TSource>,
selector: (value: TSource, index: number) => TResult | Promise<TResult> = identityAsync,
thisArg?: any
): AsyncIterableX<TResult> {
Expand All @@ -57,10 +81,7 @@ export abstract class AsyncIterableX<T> implements AsyncIterable<T> {
if (isArrayLike(source)) {
return new FromArrayIterable<TSource, TResult>(source, fn);
}
return new FromAsyncIterable<TSource, TResult>(
new OfAsyncIterable<TSource>([source as TSource]),
fn
);
throw new TypeError('Input type not supported');
/* tslint:enable */
}

Expand Down
Loading

0 comments on commit 5e2a1b6

Please sign in to comment.