Skip to content

Fix map() #1271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions packages/firestore/src/local/persistence_promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,26 @@ export class PersistencePromise<T> {

static map<R>(all: Iterable<PersistencePromise<R>>): PersistencePromise<R[]> {
const results: R[] = [];
return PersistencePromise.forEach(all, result => {
results.push(result);
return PersistencePromise.resolve();
}).next(() => results);
const promises: Array<PersistencePromise<void>> = [];

const it = all[Symbol.iterator]();
let result = it.next();
let count = 0;
while (!result.done) {
const value = result.value;
const index = count;

promises.push(
value.next(val => {
results[index] = val;
})
);

result = it.next();
++count;
}

return PersistencePromise.waitFor(promises).next(() => results);
}

static forEach<T>(
Expand Down
59 changes: 59 additions & 0 deletions packages/firestore/test/unit/local/persistence_promise.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

import { expect } from 'chai';
import { PersistencePromise } from '../../../src/local/persistence_promise';
import { Deferred } from '../../../src/util/promise';

import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';

chai.use(chaiAsPromised);

describe('PersistencePromise', () => {
function async<R>(value: R): PersistencePromise<R> {
Expand Down Expand Up @@ -214,6 +220,17 @@ describe('PersistencePromise', () => {
.toPromise();
});

it('propagates error for waitFor()', () => {
const resolved = PersistencePromise.resolve('resolved');
const rejected: PersistencePromise<string> = PersistencePromise.reject(
new Error('rejected')
);

const p = PersistencePromise.waitFor([resolved, rejected]).toPromise();

return expect(p).to.be.eventually.rejectedWith('rejected');
});

it('executes forEach in order', async () => {
let result = '';
await PersistencePromise.forEach(['a', 'b', 'c'], el => {
Expand All @@ -222,4 +239,46 @@ describe('PersistencePromise', () => {
}).toPromise();
expect(result).to.equal('abc');
});

it('propagates error for forEach()', () => {
const p = PersistencePromise.forEach([true, false], success => {
if (success) {
return PersistencePromise.resolve();
} else {
return PersistencePromise.reject(new Error('rejected'));
}
}).toPromise();

return expect(p).to.be.eventually.rejectedWith('rejected');
});

it('maintains order for map()', async () => {
const deferred = new Deferred<void>();

const pending = new PersistencePromise<string>(resolve => {
return deferred.promise.then(() => resolve('first'));
});
const resolved = PersistencePromise.resolve('second');

const p = PersistencePromise.map([pending, resolved]).next(results => {
expect(results).to.deep.eq(['first', 'second']);
return PersistencePromise.resolve();
});

setImmediate(() => {
deferred.resolve();
});

await p.toPromise();
});

it('propagates error for map()', () => {
const resolved = PersistencePromise.resolve('resolved');
const rejected: PersistencePromise<string> = PersistencePromise.reject(
new Error('rejected')
);

const p = PersistencePromise.map([resolved, rejected]).toPromise();
return expect(p).to.be.eventually.rejectedWith('rejected');
});
});
2 changes: 1 addition & 1 deletion packages/firestore/test/unit/local/simple_db.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ describe('SimpleDb', () => {
for (let i = 0; i < 1000; ++i) {
promises.push(store.get(i));
}
return PersistencePromise.map(promises).next(() => {
return PersistencePromise.waitFor(promises).next(() => {
const end = new Date().getTime();
// tslint:disable-next-line:no-console
console.log(`Reading: ${end - start} ms`);
Expand Down