Skip to content

Commit

Permalink
test(NODE-6099): add aggregation building unit coverage (#4088)
Browse files Browse the repository at this point in the history
Co-authored-by: Aditi Khare <106987683+aditi-khare-mongoDB@users.noreply.github.com>
  • Loading branch information
nbbeeken and aditi-khare-mongoDB committed Apr 18, 2024
1 parent a6882ec commit 322d9e8
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 64 deletions.
64 changes: 0 additions & 64 deletions test/integration/crud/aggregation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -939,68 +939,4 @@ describe('Aggregation', function () {
.finally(() => client.close());
}
});

it('should return identical results for array aggregations and builder aggregations', async function () {
const databaseName = this.configuration.db;
const db = client.db(databaseName);
const collection = db.collection(
'shouldReturnIdenticalResultsForArrayAggregationsAndBuilderAggregations'
);

const docs = [
{
title: 'this is my title',
author: 'bob',
posted: new Date(),
pageViews: 5,
tags: ['fun', 'good', 'fun'],
other: { foo: 5 },
comments: [
{ author: 'joe', text: 'this is cool' },
{ author: 'sam', text: 'this is bad' }
]
}
];

await collection.insertMany(docs, { writeConcern: { w: 1 } });
const arrayPipelineCursor = collection.aggregate([
{
$project: {
author: 1,
tags: 1
}
},
{ $unwind: '$tags' },
{
$group: {
_id: { tags: '$tags' },
authors: { $addToSet: '$author' }
}
},
{ $sort: { _id: -1 } }
]);

const builderPipelineCursor = collection
.aggregate()
.project({ author: 1, tags: 1 })
.unwind('$tags')
.group({ _id: { tags: '$tags' }, authors: { $addToSet: '$author' } })
.sort({ _id: -1 });

const builderGenericStageCursor = collection
.aggregate()
.addStage({ $project: { author: 1, tags: 1 } })
.addStage({ $unwind: '$tags' })
.addStage({ $group: { _id: { tags: '$tags' }, authors: { $addToSet: '$author' } } })
.addStage({ $sort: { _id: -1 } });

const expectedResults = [
{ _id: { tags: 'good' }, authors: ['bob'] },
{ _id: { tags: 'fun' }, authors: ['bob'] }
];

expect(await arrayPipelineCursor.toArray()).to.deep.equal(expectedResults);
expect(await builderPipelineCursor.toArray()).to.deep.equal(expectedResults);
expect(await builderGenericStageCursor.toArray()).to.deep.equal(expectedResults);
});
});
160 changes: 160 additions & 0 deletions test/unit/cursor/aggregation_cursor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { expect } from 'chai';

import { type AggregationCursor, MongoClient } from '../../mongodb';

describe('class AggregationCursor', () => {
let client: MongoClient;
let cursor: AggregationCursor;

beforeEach(async function () {
client = new MongoClient('mongodb://iLoveJavascript');
cursor = client.db().aggregate();
});

afterEach(async function () {
await cursor.close();
await client.close();
});

context('get pipeline()', () => {
it('returns the current aggregation pipeline', () => {
expect(cursor.pipeline).to.deep.equal([]);
});
});

context('clone()', () => {
it('returns a new cursor with a different session', () => {
const cloned = cursor.clone();
expect(cursor).to.not.equal(cloned);
expect(cursor.session).to.not.equal(cloned.session);
});
});

context('map()', () => {
/*
* map does not actually return a new cursor,
* the method exists to allow typescript to redefine the output based on the transform
*/
it('returns the same cursor instance', () => {
const mappedCursor = cursor.map(() => ({ blah: 1 }));
expect(cursor).to.equal(mappedCursor);
});
});

context('geoNear()', () => {
it('adds a $geoNear stage', () => {
cursor.geoNear({ lat: 1, lon: 1 });
expect(cursor.pipeline).to.have.deep.property('0', { $geoNear: { lat: 1, lon: 1 } });
});
});

context('unwind()', () => {
it('adds a $unwind stage', () => {
cursor.unwind({ blah: 1 });
expect(cursor.pipeline).to.have.deep.property('0', { $unwind: { blah: 1 } });
});
});

context('sort()', () => {
it('adds a $sort stage', () => {
cursor.sort({ _id: -1 });
expect(cursor.pipeline).to.have.deep.property('0', { $sort: { _id: -1 } });
});
});

context('skip()', () => {
it('adds a $skip stage', () => {
cursor.skip(2);
expect(cursor.pipeline).to.have.deep.property('0', { $skip: 2 });
});
});

context('redact()', () => {
it('adds a $redact stage', () => {
cursor.redact({ redact: true });
expect(cursor.pipeline).to.have.deep.property('0', { $redact: { redact: true } });
});
});

context('lookup()', () => {
it('adds a $lookup stage', () => {
cursor.lookup({ lookup: true });
expect(cursor.pipeline).to.have.deep.property('0', { $lookup: { lookup: true } });
});
});

context('project()', () => {
it('adds a $project stage', () => {
cursor.project({ project: true });
expect(cursor.pipeline).to.have.deep.property('0', { $project: { project: true } });
});
});

context('out()', () => {
it('adds a $out stage', () => {
cursor.out({ db: 'a', coll: 'b' });
expect(cursor.pipeline).to.have.deep.property('0', { $out: { db: 'a', coll: 'b' } });
});
});

context('match()', () => {
it('adds a $match stage', () => {
cursor.match({ match: true });
expect(cursor.pipeline).to.have.deep.property('0', { $match: { match: true } });
});
});

context('limit()', () => {
it('adds a $limit stage', () => {
cursor.limit(2);
expect(cursor.pipeline).to.have.deep.property('0', { $limit: 2 });
});
});

context('group()', () => {
it('adds a $group stage', () => {
cursor.group({ group: true });
expect(cursor.pipeline).to.have.deep.property('0', { $group: { group: true } });
});
});

context('addStage()', () => {
it('adds an arbitrary stage', () => {
cursor.addStage({ $iLoveJavascriptStage: { yes: true } });
expect(cursor.pipeline).to.have.deep.property('0', { $iLoveJavascriptStage: { yes: true } });
});
});

context('when addStage, bespoke stage methods, or array is used to construct pipeline', () => {
it('sets deeply identical aggregations pipelines', () => {
const collection = client.db().collection('test');

const expectedPipeline = [
{ $project: { author: 1, tags: 1 } },
{ $unwind: '$tags' },
{ $group: { _id: { tags: '$tags' }, authors: { $addToSet: '$author' } } },
{ $sort: { _id: -1 } }
];

const arrayPipelineCursor = collection.aggregate(Array.from(expectedPipeline));

const builderPipelineCursor = collection
.aggregate()
.project({ author: 1, tags: 1 })
.unwind('$tags')
.group({ _id: { tags: '$tags' }, authors: { $addToSet: '$author' } })
.sort({ _id: -1 });

const builderGenericStageCursor = collection
.aggregate()
.addStage({ $project: { author: 1, tags: 1 } })
.addStage({ $unwind: '$tags' })
.addStage({ $group: { _id: { tags: '$tags' }, authors: { $addToSet: '$author' } } })
.addStage({ $sort: { _id: -1 } });

expect(arrayPipelineCursor.pipeline).to.deep.equal(expectedPipeline);
expect(builderPipelineCursor.pipeline).to.deep.equal(expectedPipeline);
expect(builderGenericStageCursor.pipeline).to.deep.equal(expectedPipeline);
});
});
});

0 comments on commit 322d9e8

Please sign in to comment.