Skip to content

Commit 1f5b716

Browse files
authored
chore(NODE-6844): modernize mocha defer plugin and remove incorrect usages (#4456)
1 parent d9c7afc commit 1f5b716

File tree

4 files changed

+164
-155
lines changed

4 files changed

+164
-155
lines changed

global.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ declare global {
8484

8585
interface Context {
8686
configuration: TestConfiguration;
87+
/** @deprecated Please use afterEach hooks instead */
88+
defer(fn: () => Promise<unknown>): void;
8789
}
8890

8991
interface Test {

test/integration/change-streams/change_stream.test.ts

+80-71
Original file line numberDiff line numberDiff line change
@@ -209,74 +209,78 @@ describe('Change Streams', function () {
209209
}
210210
});
211211

212-
it('should support creating multiple simultaneous ChangeStreams', {
213-
metadata: { requires: { topology: 'replicaset' } },
212+
describe('when creating multiple simultaneous ChangeStreams', () => {
213+
let client;
214+
let changeStream1;
215+
let changeStream2;
216+
let changeStream3;
214217

215-
test: function (done) {
216-
const configuration = this.configuration;
217-
const client = configuration.newClient();
218+
beforeEach(async function () {
219+
client = this.configuration.newClient();
220+
});
218221

219-
client.connect((err, client) => {
220-
expect(err).to.not.exist;
221-
this.defer(() => client.close());
222+
afterEach(async function () {
223+
await changeStream1?.close();
224+
await changeStream2?.close();
225+
await changeStream3?.close();
226+
await client?.close();
227+
});
222228

229+
it(
230+
'supports simultaneous parallel ChangeStream use',
231+
{ requires: { topology: '!single' } },
232+
async function () {
223233
const database = client.db('integration_tests');
224234
const collection1 = database.collection('simultaneous1');
225235
const collection2 = database.collection('simultaneous2');
226236

227-
const changeStream1 = collection1.watch([{ $addFields: { changeStreamNumber: 1 } }]);
228-
this.defer(() => changeStream1.close());
229-
const changeStream2 = collection2.watch([{ $addFields: { changeStreamNumber: 2 } }]);
230-
this.defer(() => changeStream2.close());
231-
const changeStream3 = collection2.watch([{ $addFields: { changeStreamNumber: 3 } }]);
232-
this.defer(() => changeStream3.close());
237+
changeStream1 = collection1.watch([{ $addFields: { changeStreamNumber: 1 } }]);
238+
changeStream2 = collection2.watch([{ $addFields: { changeStreamNumber: 2 } }]);
239+
changeStream3 = collection2.watch([{ $addFields: { changeStreamNumber: 3 } }]);
233240

234241
setTimeout(() => {
235-
this.defer(
236-
collection1.insertMany([{ a: 1 }]).then(() => collection2.insertMany([{ a: 1 }]))
237-
);
242+
collection1.insertMany([{ a: 1 }]).then(() => collection2.insertMany([{ a: 1 }]));
238243
}, 50);
239244

240-
Promise.resolve()
241-
.then(() =>
242-
Promise.all([changeStream1.hasNext(), changeStream2.hasNext(), changeStream3.hasNext()])
243-
)
244-
.then(function (hasNexts) {
245-
// Check all the Change Streams have a next item
246-
assert.ok(hasNexts[0]);
247-
assert.ok(hasNexts[1]);
248-
assert.ok(hasNexts[2]);
249-
250-
return Promise.all([changeStream1.next(), changeStream2.next(), changeStream3.next()]);
251-
})
252-
.then(function (changes) {
253-
// Check the values of the change documents are correct
254-
assert.equal(changes[0].operationType, 'insert');
255-
assert.equal(changes[1].operationType, 'insert');
256-
assert.equal(changes[2].operationType, 'insert');
257-
258-
expect(changes[0]).to.have.nested.property('fullDocument.a', 1);
259-
expect(changes[1]).to.have.nested.property('fullDocument.a', 1);
260-
expect(changes[2]).to.have.nested.property('fullDocument.a', 1);
261-
262-
expect(changes[0]).to.have.nested.property('ns.db', 'integration_tests');
263-
expect(changes[1]).to.have.nested.property('ns.db', 'integration_tests');
264-
expect(changes[2]).to.have.nested.property('ns.db', 'integration_tests');
265-
266-
expect(changes[0]).to.have.nested.property('ns.coll', 'simultaneous1');
267-
expect(changes[1]).to.have.nested.property('ns.coll', 'simultaneous2');
268-
expect(changes[2]).to.have.nested.property('ns.coll', 'simultaneous2');
269-
270-
expect(changes[0]).to.have.nested.property('changeStreamNumber', 1);
271-
expect(changes[1]).to.have.nested.property('changeStreamNumber', 2);
272-
expect(changes[2]).to.have.nested.property('changeStreamNumber', 3);
273-
})
274-
.then(
275-
() => done(),
276-
err => done(err)
277-
);
278-
});
279-
}
245+
const hasNexts = await Promise.all([
246+
changeStream1.hasNext(),
247+
changeStream2.hasNext(),
248+
changeStream3.hasNext()
249+
]);
250+
251+
// Check all the Change Streams have a next item
252+
expect(hasNexts[0]).to.be.true;
253+
expect(hasNexts[1]).to.be.true;
254+
expect(hasNexts[2]).to.be.true;
255+
256+
const changes = await Promise.all([
257+
changeStream1.next(),
258+
changeStream2.next(),
259+
changeStream3.next()
260+
]);
261+
262+
// Check the values of the change documents are correct
263+
expect(changes[0].operationType).to.be.equal('insert');
264+
expect(changes[1].operationType).to.be.equal('insert');
265+
expect(changes[2].operationType).to.be.equal('insert');
266+
267+
expect(changes[0]).to.have.nested.property('fullDocument.a', 1);
268+
expect(changes[1]).to.have.nested.property('fullDocument.a', 1);
269+
expect(changes[2]).to.have.nested.property('fullDocument.a', 1);
270+
271+
expect(changes[0]).to.have.nested.property('ns.db', 'integration_tests');
272+
expect(changes[1]).to.have.nested.property('ns.db', 'integration_tests');
273+
expect(changes[2]).to.have.nested.property('ns.db', 'integration_tests');
274+
275+
expect(changes[0]).to.have.nested.property('ns.coll', 'simultaneous1');
276+
expect(changes[1]).to.have.nested.property('ns.coll', 'simultaneous2');
277+
expect(changes[2]).to.have.nested.property('ns.coll', 'simultaneous2');
278+
279+
expect(changes[0]).to.have.nested.property('changeStreamNumber', 1);
280+
expect(changes[1]).to.have.nested.property('changeStreamNumber', 2);
281+
expect(changes[2]).to.have.nested.property('changeStreamNumber', 3);
282+
}
283+
);
280284
});
281285

282286
it('should properly close ChangeStream cursor', {
@@ -806,23 +810,28 @@ describe('Change Streams', function () {
806810
});
807811

808812
it('when invoked with promises', {
809-
metadata: { requires: { topology: 'replicaset' } },
810-
test: function () {
811-
const read = () => {
812-
return Promise.resolve()
813-
.then(() => changeStream.next())
814-
.then(() => changeStream.next())
815-
.then(() => {
816-
this.defer(lastWrite());
817-
const nextP = changeStream.next();
818-
return changeStream.close().then(() => nextP);
819-
});
813+
metadata: { requires: { topology: '!single' } },
814+
test: async function () {
815+
const read = async () => {
816+
await changeStream.next();
817+
await changeStream.next();
818+
819+
const write = lastWrite();
820+
821+
const nextP = changeStream.next();
822+
823+
await changeStream.close();
824+
825+
await write;
826+
await nextP;
820827
};
821828

822-
return Promise.all([read(), write()]).then(
823-
() => Promise.reject(new Error('Expected operation to fail with error')),
824-
err => expect(err.message).to.equal('ChangeStream is closed')
829+
const error = await Promise.all([read(), write()]).then(
830+
() => null,
831+
error => error
825832
);
833+
834+
expect(error.message).to.equal('ChangeStream is closed');
826835
}
827836
});
828837

test/integration/change-streams/change_streams.prose.test.ts

+39-36
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,9 @@ const initIteratorMode = async (cs: ChangeStream) => {
8080
};
8181

8282
/** Waits for a change stream to start */
83-
function waitForStarted(changeStream, callback) {
84-
changeStream.cursor.once('init', () => {
85-
callback();
86-
});
83+
async function waitForStarted(changeStream, callback) {
84+
await once(changeStream.cursor, 'init');
85+
await callback();
8786
}
8887

8988
// Define the pipeline processing changes
@@ -844,42 +843,48 @@ describe('Change Stream prose tests', function () {
844843
describe('Change Stream prose 17-18', function () {
845844
let client: MongoClient;
846845
let coll: Collection;
847-
let startAfter;
846+
let startAfter: unknown;
848847

849848
function recordEvent(events, e) {
850849
if (e.commandName !== 'aggregate') return;
851850
events.push({ $changeStream: e.command.pipeline[0].$changeStream });
852851
}
853852

854-
beforeEach(function (done) {
853+
beforeEach('get startAfter token', async function () {
855854
const configuration = this.configuration;
856-
client = configuration.newClient({ monitorCommands: true });
857-
client.connect(err => {
858-
expect(err).to.not.exist;
859-
coll = client.db('integration_tests').collection('setupAfterTest');
860-
const changeStream = coll.watch();
861-
changeStream.on('error', done);
862-
waitForStarted(changeStream, () => {
863-
coll.insertOne({ x: 1 }, { writeConcern: { w: 'majority', j: true } }, err => {
864-
expect(err).to.not.exist;
855+
const utilClient = configuration.newClient();
856+
await utilClient.connect();
865857

866-
coll.drop(err => {
867-
expect(err).to.not.exist;
868-
});
869-
});
870-
});
858+
const coll = utilClient.db('integration_tests').collection('setupAfterTest');
859+
const changeStream = coll.watch();
871860

872-
changeStream.on('change', change => {
873-
if (change.operationType === 'invalidate') {
874-
startAfter = change._id;
875-
changeStream.close(done);
876-
}
877-
});
878-
});
861+
const willInit = once(changeStream.cursor, 'init');
862+
863+
await changeStream.tryNext();
864+
await willInit;
865+
866+
await coll.insertOne({ x: 1 }, { writeConcern: { w: 'majority', j: true } });
867+
await coll.drop();
868+
869+
for await (const change of changeStream) {
870+
if (change.operationType === 'invalidate') {
871+
startAfter = change._id;
872+
break;
873+
}
874+
}
875+
876+
await changeStream.close();
877+
878+
await utilClient.close();
879879
});
880880

881-
afterEach(function (done) {
882-
client.close(done);
881+
beforeEach(async function () {
882+
client = this.configuration.newClient({}, { monitorCommands: true });
883+
coll = client.db('integration_tests').collection('setupAfterTest');
884+
});
885+
886+
afterEach(async function () {
887+
await client.close();
883888
});
884889

885890
// 17. $changeStream stage for ChangeStream started with startAfter against a server >=4.1.1
@@ -894,8 +899,8 @@ describe('Change Stream prose tests', function () {
894899
client.on('commandStarted', e => recordEvent(events, e));
895900
const changeStream = coll.watch([], { startAfter });
896901

897-
changeStream.on('error', async e => {
898-
await changeStream.close(e);
902+
changeStream.on('error', async () => {
903+
await changeStream.close();
899904
});
900905

901906
const changePromise = once(changeStream, 'change');
@@ -955,11 +960,9 @@ describe('Change Stream prose tests', function () {
955960
});
956961

957962
waitForStarted(changeStream, () =>
958-
this.defer(
959-
coll
960-
.insertOne({ x: 2 }, { writeConcern: { w: 'majority', j: true } })
961-
.then(() => coll.insertOne({ x: 3 }, { writeConcern: { w: 'majority', j: true } }))
962-
)
963+
coll
964+
.insertOne({ x: 2 }, { writeConcern: { w: 'majority', j: true } })
965+
.then(() => coll.insertOne({ x: 3 }, { writeConcern: { w: 'majority', j: true } }))
963966
);
964967
}
965968
});

0 commit comments

Comments
 (0)