-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Cursor): adds support for AsyncIterator in cursors
Adds support for async iterators in cursors, allowing users to use for..await..of blocks on cursors. Note: this is only loaded if Symbol.asyncIterator is supported (v10.x). Fixes NODE-1684 test: adds single file responsible for loading esnext tests Now use a single file to load tests that cannot run in current env
- Loading branch information
1 parent
92e2580
commit b972c1e
Showing
9 changed files
with
169 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"parserOptions": { | ||
"ecmaVersion": 2018 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use strict'; | ||
|
||
async function* asyncIterator() { | ||
while (true) { | ||
const value = await this.next(); | ||
if (!value) { | ||
await this.close(); | ||
return; | ||
} | ||
|
||
yield value; | ||
} | ||
} | ||
|
||
exports.asyncIterator = asyncIterator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
'use strict'; | ||
|
||
function loadTests() { | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
const directory = path.resolve.apply(path, arguments); | ||
fs | ||
.readdirSync(directory) | ||
.filter(filePath => filePath.match(/.*\.js$/)) | ||
.map(filePath => path.resolve(directory, filePath)) | ||
.forEach(x => require(x)); | ||
} | ||
|
||
describe('ES2017', function() { | ||
let supportES2017 = false; | ||
try { | ||
new Function('return (async function foo() {})();')(); | ||
supportES2017 = true; | ||
} catch (e) { | ||
supportES2017 = false; | ||
} | ||
|
||
if (supportES2017) { | ||
loadTests(__dirname, '..', 'examples'); | ||
} else { | ||
it.skip('skipping ES2017 tests due to insufficient node version', function() {}); | ||
} | ||
}); | ||
|
||
describe('ES2018', function() { | ||
const supportES2018 = !!Symbol.asyncIterator; | ||
|
||
if (supportES2018) { | ||
loadTests(__dirname, '..', 'node-next', 'es2018'); | ||
} else { | ||
it.skip('skipping ES2018 tests due to insufficient node version', function() {}); | ||
} | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"parserOptions": { | ||
"ecmaVersion": 2018 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
'use strict'; | ||
|
||
const { expect } = require('chai'); | ||
const { MongoError } = require('../../../index'); | ||
|
||
describe('Cursor Async Iterator Tests', function() { | ||
let client, collection; | ||
before(async function() { | ||
client = this.configuration.newClient(); | ||
|
||
await client.connect(); | ||
const docs = Array.from({ length: 1000 }).map((_, index) => ({ foo: index, bar: 1 })); | ||
|
||
collection = client.db(this.configuration.db).collection('async_cursor_tests'); | ||
|
||
await collection.deleteMany({}); | ||
await collection.insertMany(docs); | ||
await client.close(); | ||
}); | ||
|
||
beforeEach(async function() { | ||
client = this.configuration.newClient(); | ||
await client.connect(); | ||
collection = client.db(this.configuration.db).collection('async_cursor_tests'); | ||
}); | ||
|
||
afterEach(() => client.close()); | ||
|
||
it('should be able to use a for-await loop on a find command cursor', { | ||
metadata: { requires: { node: '>=10.5.0' } }, | ||
test: async function() { | ||
const cursor = collection.find({ bar: 1 }); | ||
|
||
let counter = 0; | ||
for await (const doc of cursor) { | ||
expect(doc).to.have.property('bar', 1); | ||
counter += 1; | ||
} | ||
|
||
expect(counter).to.equal(1000); | ||
} | ||
}); | ||
|
||
it('should be able to use a for-await loop on an aggregation cursor', { | ||
metadata: { requires: { node: '>=10.5.0' } }, | ||
test: async function() { | ||
const cursor = collection.aggregate([{ $match: { bar: 1 } }]); | ||
|
||
let counter = 0; | ||
for await (const doc of cursor) { | ||
expect(doc).to.have.property('bar', 1); | ||
counter += 1; | ||
} | ||
|
||
expect(counter).to.equal(1000); | ||
} | ||
}); | ||
|
||
it('should be able to use a for-await loop on a command cursor', { | ||
metadata: { requires: { node: '>=10.5.0', mongodb: '>=3.0.0' } }, | ||
test: async function() { | ||
const cursor1 = collection.listIndexes(); | ||
const cursor2 = collection.listIndexes(); | ||
|
||
const indexes = await cursor1.toArray(); | ||
let counter = 0; | ||
for await (const doc of cursor2) { | ||
expect(doc).to.exist; | ||
counter += 1; | ||
} | ||
|
||
expect(counter).to.equal(indexes.length); | ||
} | ||
}); | ||
|
||
it('should properly error when cursor is closed', { | ||
metadata: { requires: { node: '>=10.5.0' } }, | ||
test: async function() { | ||
const cursor = collection.find(); | ||
|
||
try { | ||
for await (const doc of cursor) { | ||
expect(doc).to.exist; | ||
cursor.close(); | ||
} | ||
throw new Error('expected closing the cursor to break iteration'); | ||
} catch (e) { | ||
expect(e).to.be.an.instanceOf(MongoError); | ||
} | ||
} | ||
}); | ||
}); |
b972c1e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, since the update to 3.2.1, I get this error when I try to start node and it seems related to this code specifically, I do not know how to fix it, any help would be appreciated.
using [email protected]
using [email protected]
b972c1e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wangrenyn If you we're trying to reply, I think your comment was cut off?
b972c1e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simplecommerce would you mind opening a JIRA ticket for this? It's difficult to have comment threads on individual commits. In the ticket, could you please tell us if there is anything special about your application (are you webpacking for instance)? We run integration tests against node carbon on both travis and evergreen, and I just did a test run locally with v8.10.0 specifically and it's running without this issue.