From 6557032681a48d819de4fe5bfc4c2e8f327935f8 Mon Sep 17 00:00:00 2001 From: Alena Khineika Date: Mon, 8 Jul 2024 19:42:06 +0200 Subject: [PATCH] fix(shell-api): the explainable cursor should reflect simple collation MONGOSH-1670 (#2050) --- packages/shell-api/src/explainable.spec.ts | 102 ++++++++++++++------- packages/shell-api/src/explainable.ts | 6 +- packages/shell-api/src/integration.spec.ts | 13 +++ 3 files changed, 88 insertions(+), 33 deletions(-) diff --git a/packages/shell-api/src/explainable.spec.ts b/packages/shell-api/src/explainable.spec.ts index c6daa6c2a..f59e1e7ef 100644 --- a/packages/shell-api/src/explainable.spec.ts +++ b/packages/shell-api/src/explainable.spec.ts @@ -110,46 +110,86 @@ describe('Explainable', function () { }); describe('find', function () { - let cursorStub; - let explainResult; - beforeEach(async function () { - explainResult = { ok: 1 }; + context('without options', function () { + let cursorStub; + let explainResult; - const cursorSpy = { - explain: sinon.spy(() => explainResult), - } as unknown; - collection.find = sinon.spy(() => Promise.resolve(cursorSpy as Cursor)); + beforeEach(async function () { + explainResult = { ok: 1 }; - cursorStub = await explainable.find({ query: 1 }, { projection: 1 }); - }); + const cursorSpy = { + explain: sinon.spy(() => explainResult), + } as unknown; + collection.find = sinon.spy(() => + Promise.resolve(cursorSpy as Cursor) + ); - it('calls collection.find with arguments', function () { - expect(collection.find).to.have.been.calledOnceWithExactly( - { query: 1 }, - { projection: 1 } - ); - }); + cursorStub = await explainable.find({ query: 1 }, { projection: 1 }); + }); + + it('calls collection.find with arguments', function () { + expect(collection.find).to.have.been.calledOnceWithExactly( + { query: 1 }, + { projection: 1 }, + {} + ); + }); + + it('returns an cursor that has toShellResult when evaluated', async function () { + expect((await toShellResult(cursorStub)).type).to.equal( + 'ExplainableCursor' + ); + }); + + context( + 'when calling toShellResult().printable on the result', + function () { + it('calls explain with verbosity', function () { + expect(cursorStub._verbosity).to.equal('queryPlanner'); + }); - it('returns an cursor that has toShellResult when evaluated', async function () { - expect((await toShellResult(cursorStub)).type).to.equal( - 'ExplainableCursor' + it('returns the explain result', async function () { + expect((await toShellResult(cursorStub)).printable).to.equal( + explainResult + ); + }); + } ); }); - context( - 'when calling toShellResult().printable on the result', - function () { - it('calls explain with verbosity', function () { - expect(cursorStub._verbosity).to.equal('queryPlanner'); - }); + context('with options', function () { + let cursorStub; + let explainResult; + + beforeEach(async function () { + explainResult = { ok: 1 }; + + const cursorSpy = { + explain: sinon.spy(() => explainResult), + } as unknown; + collection.find = sinon.spy(() => + Promise.resolve(cursorSpy as Cursor) + ); - it('returns the explain result', async function () { - expect((await toShellResult(cursorStub)).printable).to.equal( - explainResult - ); + cursorStub = await explainable.find({}, undefined, { + collation: { locale: 'simple' }, }); - } - ); + }); + + it('calls collection.find with arguments', function () { + expect(collection.find).to.have.been.calledOnceWithExactly( + {}, + undefined, + { collation: { locale: 'simple' } } + ); + }); + + it('returns an cursor that has toShellResult when evaluated', async function () { + expect((await toShellResult(cursorStub)).type).to.equal( + 'ExplainableCursor' + ); + }); + }); }); describe('aggregate', function () { diff --git a/packages/shell-api/src/explainable.ts b/packages/shell-api/src/explainable.ts index c3a924023..393840af8 100644 --- a/packages/shell-api/src/explainable.ts +++ b/packages/shell-api/src/explainable.ts @@ -31,6 +31,7 @@ import type { FindOneAndDeleteOptions, FindOneAndReplaceOptions, FindOneAndUpdateOptions, + FindOptions, } from '@mongosh/service-provider-core'; @shellApiClassDefault @@ -97,11 +98,12 @@ export default class Explainable extends ShellApiWithMongoClass { @returnsPromise async find( query?: Document, - projection?: Document + projection?: Document, + options: FindOptions = {} ): Promise { this._emitExplainableApiCall('find', { query, projection }); - const cursor = await this._collection.find(query, projection); + const cursor = await this._collection.find(query, projection, options); return new ExplainableCursor(this._mongo, cursor, this._verbosity); } diff --git a/packages/shell-api/src/integration.spec.ts b/packages/shell-api/src/integration.spec.ts index 8847ef9a3..b7fcb37a2 100644 --- a/packages/shell-api/src/integration.spec.ts +++ b/packages/shell-api/src/integration.spec.ts @@ -1568,6 +1568,19 @@ describe('Shell API (integration)', function () { 'serverInfo', ]); }); + + describe('after server 4.4', function () { + skipIfServerVersion(testServer, '<= 4.4'); + it('the explainable cursor reflects collation', async function () { + const cursor = await explainable.find({}, undefined, { + collation: { locale: 'simple' }, + }); + const result = await toShellResult(cursor); + expect(result.printable.command.collation.locale).to.be.equal( + 'simple' + ); + }); + }); }); describe('aggregate', function () {