diff --git a/lib/make/optimize-join-and-where.js b/lib/make/optimize-join-and-where.js index 2d30c01..6a6dbff 100644 --- a/lib/make/optimize-join-and-where.js +++ b/lib/make/optimize-join-and-where.js @@ -8,7 +8,6 @@ const {get, isEqual, cloneDeep} = require('lodash'); * @typedef {import('../types').OptimizationProcessResult} ProcessResult */ -const optimizationsEnabled = false; /** * * @param {import('../types').PipelineFn[]} pipeline @@ -18,9 +17,9 @@ const optimizationsEnabled = false; * @returns {void} */ function optimizeJoinAndWhere(pipeline, pipeLineJoin, wherePiece, context) { - if (!optimizationsEnabled || context.joinHints.includes('nooptimize')) { + if (!context.optimizeJoins || context.joinHints.includes('nooptimize')) { pushToPipeline({ - wasOptimised: false, + wasOptimized: false, leftOverMatches: [], }); return; @@ -35,7 +34,7 @@ function optimizeJoinAndWhere(pipeline, pipeLineJoin, wherePiece, context) { (!context.joinHints || !context.joinHints.includes('nooptimize')) ) { try { - const result = recursivelyOptimise( + const result = recursivelyOptimize( wherePiece.$match, lookup, pipeline, @@ -48,25 +47,25 @@ function optimizeJoinAndWhere(pipeline, pipeLineJoin, wherePiece, context) { clearObjectAndCopyToIt(pipeLineJoin, originalPipelineJoin); clearObjectAndCopyToIt(wherePiece, originalWherePiece); pushToPipeline({ - wasOptimised: false, + wasOptimized: false, leftOverMatches: [], }); } } else { pushToPipeline({ - wasOptimised: false, + wasOptimized: false, leftOverMatches: [], }); } /** - * @param { OptimizationProcessResult } result + * @param { Pick } result */ - function pushToPipeline({leftOverMatches, wasOptimised}) { + function pushToPipeline({leftOverMatches, wasOptimized}) { for (const join of pipeLineJoin) { pipeline.push(join); } - if (!wasOptimised && wherePiece) { + if (!wasOptimized && wherePiece) { pipeline.push(wherePiece); return; } @@ -88,7 +87,7 @@ function optimizeJoinAndWhere(pipeline, pipeLineJoin, wherePiece, context) { * @param {ProcessResult} [parentResult] * @returns {ProcessResult} the leftover matches to add to the end */ -function recursivelyOptimise( +function recursivelyOptimize( match, lookup, pipeline, @@ -171,7 +170,7 @@ function recursivelyOptimise( if (miscMatches.length > 0) { mergeProcessResults( { - wasOptimised: false, + wasOptimized: false, leftOverMatches: miscMatches, lookupPipelineStagesAdded: [], pipelineStagesAdded: [], @@ -277,7 +276,7 @@ function processMatches( const returnResult = newReturnResult(); const results = []; for (const match of matches) { - const res = recursivelyOptimise( + const res = recursivelyOptimize( match, lookup, pipeline, @@ -303,7 +302,7 @@ function processMatches( * @param {ProcessResult} currentResult * @param {MatchType} parentMatchType * @param {boolean} addSingle - * @returns {ProcessResult} wasOptimised + * @returns {ProcessResult} wasOptimized */ function processSourceMatches( sourceMatches, @@ -325,7 +324,7 @@ function processSourceMatches( target[parentMatchType].push({[matchType]: [...sourceMatches]}); } clearArray(sourceMatches); - returnResult.wasOptimised = true; + returnResult.wasOptimized = true; return returnResult; } let newStage; @@ -351,7 +350,7 @@ function processSourceMatches( pipeline.push(newStage); returnResult.pipelineStagesAdded.push(newStage); clearArray(sourceMatches); - returnResult.wasOptimised = true; + returnResult.wasOptimized = true; return returnResult; /** @@ -404,12 +403,12 @@ function processDestinationMatches( if (destinationMatches.length === 0 && leftOverSourceMatches.length === 0) { return returnResult; } - // ensures the lookup is in the right format to be optimised + // ensures the lookup is in the right format to be optimized if (!lookup.$lookup.pipeline) { convertLookupToPipeline(lookup); } else { if (currentResult.lookupPipelineStagesAdded === 0) { - // only optimise the pipeline if we haven't already done int + // only optimize the pipeline if we haven't already done int optimizeExistingPipeline(lookup); } } @@ -435,12 +434,12 @@ function processDestinationMatches( } else { target.push(...mappedMatches); } - returnResult.wasOptimised = true; + returnResult.wasOptimized = true; return returnResult; } const newStage = getStage(); lookup.$lookup.pipeline.unshift(newStage); - returnResult.wasOptimised = true; + returnResult.wasOptimized = true; returnResult.lookupPipelineStagesAdded.push(newStage); return returnResult; @@ -518,7 +517,7 @@ function processDestinationMatches( */ function optimizeExistingPipeline(lookup) { const matches = lookup.$lookup.pipeline.filter((p) => !!p.$match); - // optimise the existing pipeline + // optimize the existing pipeline let indexesToDelete = []; for (const match of matches) { if (match.$match.$expr.$and) { @@ -649,7 +648,7 @@ function mapMatchesToExpressionFormat(match, sourceName, explicitKey) { */ function newReturnResult() { return { - wasOptimised: false, + wasOptimized: false, leftOverMatches: [], pipelineStagesAdded: [], lookupPipelineStagesAdded: [], @@ -661,8 +660,8 @@ function newReturnResult() { * @param {ProcessResult} destination */ function mergeProcessResults(source, destination) { - if (source.wasOptimised) { - destination.wasOptimised = true; + if (source.wasOptimized) { + destination.wasOptimized = true; } for (const leftOverMatch of source.leftOverMatches) { const exists = destination.leftOverMatches.some((match) => diff --git a/lib/types.ts b/lib/types.ts index f75d187..d200231 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -190,6 +190,8 @@ export interface ParserOptions { unsetId?: boolean; /** If provided, the library will use the schemas to generate better queries */ schemas?: Schemas; + /** If true, will optimize the join for better performance */ + optimizeJoins?: boolean; } export interface NoqlContext extends ParserOptions { @@ -347,7 +349,7 @@ export interface FindSchemaResult { } export interface OptimizationProcessResult { - wasOptimised: boolean; + wasOptimized: boolean; pipelineStagesAdded: PipelineFn[]; lookupPipelineStagesAdded: PipelineFn[]; leftOverMatches: Record[]; diff --git a/package.json b/package.json index 4edadd9..8b65d4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@synatic/noql", - "version": "4.1.8", + "version": "4.1.9", "description": "Convert SQL statements to mongo queries or aggregates", "main": "index.js", "files": [ diff --git a/test/optimizations/optimizations.json b/test/optimizations/optimizations.json index cd32ced..98ffdac 100644 --- a/test/optimizations/optimizations.json +++ b/test/optimizations/optimizations.json @@ -1044,5 +1044,8 @@ } ] } + }, + "use-cases": { + "case-1": {} } } \ No newline at end of file diff --git a/test/optimizations/optimizations.test.js b/test/optimizations/optimizations.test.js index 46c8bc4..e25615c 100644 --- a/test/optimizations/optimizations.test.js +++ b/test/optimizations/optimizations.test.js @@ -2,7 +2,7 @@ const {setup, disconnect} = require('../utils/mongo-client.js'); const {buildQueryResultTester} = require('../utils/query-tester/index.js'); const assert = require('assert'); const {isEqual} = require('lodash'); -describe.skip('optimizations', function () { +describe('optimizations', function () { this.timeout(90000); const fileName = 'optimizations'; /** @type {'test'|'write'} */ @@ -13,12 +13,9 @@ describe.skip('optimizations', function () { let queryResultTester; /** @type {import("mongodb").MongoClient} */ let mongoClient; - /** @type {import("mongodb").Db} */ - let database; before(async function () { const {client, db} = await setup(); mongoClient = client; - database = db; queryResultTester = buildQueryResultTester({ dirName, fileName, @@ -30,6 +27,7 @@ describe.skip('optimizations', function () { after(function (done) { disconnect().then(done).catch(done); }); + describe('where statements on joins', () => { /** * TODO Test for: @@ -41,7 +39,7 @@ describe.skip('optimizations', function () { * Maybe clone the where and pipeline before optimising, return errors:true and revert? */ describe('simple', () => { - it('01. should not optimise a simple join', async () => { + it('01. should not optimize a simple join', async () => { const queryString = ` SELECT *, unset(_id, o._id, i._id,o.orderDate) @@ -54,6 +52,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-01', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -91,7 +91,7 @@ describe.skip('optimizations', function () { ]) ); }); - it('02. should optimise a simple join with a where on destination', async () => { + it('02. should optimize a simple join with a where on destination', async () => { const queryString = ` SELECT *, unset(_id, o._id, i._id,o.orderDate) @@ -105,6 +105,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-02', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -159,7 +161,7 @@ describe.skip('optimizations', function () { ]) ); }); - it('03. should optimise a simple join with a where on source', async () => { + it('03. should optimize a simple join with a where on source', async () => { const queryString = ` SELECT *, unset(_id, o._id, i._id,o.orderDate) @@ -173,6 +175,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-03', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -235,6 +239,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-04', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -303,6 +309,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-05', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -379,6 +387,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-06', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -455,6 +465,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-07', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -534,6 +546,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-08', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -602,6 +616,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-09', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -678,6 +694,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-10', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -755,6 +773,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-11', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -836,6 +856,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-12', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -916,6 +938,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-13', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1000,6 +1024,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-14', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1085,6 +1111,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-15', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1162,6 +1190,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-16', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1242,6 +1272,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-17', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1323,6 +1355,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-14', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1405,6 +1439,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-19', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1482,6 +1518,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-21', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1572,6 +1610,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-22', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1663,6 +1703,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-23', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1755,6 +1797,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-24', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1847,6 +1891,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-25', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -1938,6 +1984,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-26', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2019,6 +2067,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-27', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2109,6 +2159,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-28', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2197,6 +2249,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-29', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2287,6 +2341,8 @@ describe.skip('optimizations', function () { mode, outputPipeline, expectZeroResults: true, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2379,6 +2435,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-31', mode: 'write', outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2470,6 +2528,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-32', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2552,6 +2612,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-33', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2642,6 +2704,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-34', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2730,6 +2794,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-35', mode: 'write', outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2819,6 +2885,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-36', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2912,6 +2980,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-37', mode: 'write', outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -2994,6 +3064,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-38', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -3077,6 +3149,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-39', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -3148,7 +3222,7 @@ describe.skip('optimizations', function () { ]) ); }); - it('40. should optimise a join with a where with misc', async () => { + it('40. should optimize a join with a where with misc', async () => { const queryString = ` SELECT *, unset(_id, o._id, i._id,o.orderDate) @@ -3164,6 +3238,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-40', mode: 'write', outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -3233,7 +3309,7 @@ describe.skip('optimizations', function () { ]) ); }); - it('41. should not optimise if the nooptimise join hint is included', async () => { + it('41. should not optimize if the nooptimize join hint is included', async () => { const queryString = ` SELECT *, unset(_id, o._id, i._id,o.orderDate) @@ -3249,6 +3325,8 @@ describe.skip('optimizations', function () { casePath: 'where.case-15', mode, outputPipeline, + optimizeJoins: true, + unsetId: false, }); assert( isEqual(pipeline, [ @@ -3312,5 +3390,143 @@ describe.skip('optimizations', function () { ); }); }); + + describe('use-cases', () => { + it('1. should correctly optimise the query', async () => { + const queryString = ` + SELECT T0_0."BilledPremium" AS "p0_0", + T0_0."FullTermPremium" AS "p1_0", + T0_0."Premium" AS "p2_0", + T0_0."WrittenPremium" AS "p3_0", + T1_0."PolNo" AS "p4_0", + T0_0."LineOfBus" AS "p5_0", + T0_0."EstRevenue" AS "p6_0", + T1_0."PolType" AS "p7_0", + T2_0."Name" AS "p8_0", + T3_0."Name" AS "p9_0", + T4_0."Name" AS "p10_0", + T5_0."Name" AS "p11_0", + T6_0."Name" AS "p12_0", + T0_0."EffDate" AS "p13_0", + T0_0."EnteredDate" AS "p14_0" + FROM "public"."ams360-data-warehouse-dds-buffers--afw_policytranpremium" T0_0 + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afwbasicpolinfo" T1_0 ON T0_0."PolId" = T1_0."PolId" + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afw_company" T2_0 ON T1_0."WritingCode" = T2_0."CoCode" + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afw_company" T3_0 ON T1_0."Cocode" = T3_0."CoCode" + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afw_generalledgerdepartment" T4_0 ON T1_0."GLDeptCode" = T4_0."GLDeptCode" + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afw_generalledgerdivision" T5_0 ON T1_0."GLDivCode" = T5_0."GLDivCode" + LEFT OUTER JOIN "public"."ams360-data-warehouse-dds-buffers--afw_generalledgergroup" T6_0 ON T1_0."GlGrpCode" = T6_0."GlGrpCode" + WHERE (T1_0."PolExpDate" >= '2024-09-10 00:00:00.000') + `; + const {pipeline} = await queryResultTester({ + queryString: queryString, + casePath: 'use-cases.case-1', + mode: 'write', + outputPipeline, + skipDbQuery: true, + optimizeJoins: true, + unsetId: false, + }); + assert( + isEqual(pipeline, [ + { + $project: { + T0_0: '$$ROOT', + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afwbasicpolinfo', + as: 'T1_0', + let: { + t_0_0_pol_id: '$T0_0.PolId', + }, + pipeline: [ + { + $match: { + $expr: { + $gte: [ + '$PolExpDate', + '2024-09-10 00:00:00.000', + ], + }, + }, + }, + { + $match: { + $expr: { + $eq: [ + '$PolId', + '$$t_0_0_pol_id', + ], + }, + }, + }, + ], + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afw_company', + as: 'T2_0', + localField: 'T1_0.WritingCode', + foreignField: 'CoCode', + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afw_company', + as: 'T3_0', + localField: 'T1_0.Cocode', + foreignField: 'CoCode', + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afw_generalledgerdepartment', + as: 'T4_0', + localField: 'T1_0.GLDeptCode', + foreignField: 'GLDeptCode', + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afw_generalledgerdivision', + as: 'T5_0', + localField: 'T1_0.GLDivCode', + foreignField: 'GLDivCode', + }, + }, + { + $lookup: { + from: 'ams360-data-warehouse-dds-buffers--afw_generalledgergroup', + as: 'T6_0', + localField: 'T1_0.GlGrpCode', + foreignField: 'GlGrpCode', + }, + }, + { + $project: { + p0_0: '$T0_0.BilledPremium', + p1_0: '$T0_0.FullTermPremium', + p2_0: '$T0_0.Premium', + p3_0: '$T0_0.WrittenPremium', + p4_0: '$T1_0.PolNo', + p5_0: '$T0_0.LineOfBus', + p6_0: '$T0_0.EstRevenue', + p7_0: '$T1_0.PolType', + p8_0: '$T2_0.Name', + p9_0: '$T3_0.Name', + p10_0: '$T4_0.Name', + p11_0: '$T5_0.Name', + p12_0: '$T6_0.Name', + p13_0: '$T0_0.EffDate', + p14_0: '$T0_0.EnteredDate', + }, + }, + ]) + ); + }); + }); }); }); diff --git a/test/utils/query-tester/query-tester.js b/test/utils/query-tester/query-tester.js index 55019dc..8fbd6ea 100644 --- a/test/utils/query-tester/query-tester.js +++ b/test/utils/query-tester/query-tester.js @@ -48,6 +48,8 @@ async function queryResultTester(options) { schemas, unwindJoins = false, unsetId = true, + optimizeJoins = false, + skipDbQuery = false, } = options; if (!fileName.endsWith('.json')) { fileName = fileName + '.json'; @@ -56,20 +58,24 @@ async function queryResultTester(options) { schemas, unwindJoins, unsetId, + optimizeJoins, }); const filePath = $path.resolve(dirName, fileName); /** @type {import("mongodb").Document[]} */ let results = []; - try { - results = await mongoClient - .db(dbName) - .collection(collections[0]) - .aggregate(pipeline) - .toArray(); - } catch (err) { - console.error(err); + if (!skipDbQuery) { + try { + results = await mongoClient + .db(dbName) + .collection(collections[0]) + .aggregate(pipeline) + .toArray(); + } catch (err) { + console.error(err); + } + results.map((o) => checkForMongoTypes(o, ignoreDateValues)); } - results.map((o) => checkForMongoTypes(o, ignoreDateValues)); + const obj = await readCases(filePath); if (mode === 'write') { if (outputPipeline) { @@ -77,7 +83,7 @@ async function queryResultTester(options) { } else { set(obj, casePath + '.pipeline', undefined); } - if (!expectZeroResults) { + if (!expectZeroResults && !skipDbQuery) { set(obj, casePath + '.expectedResults', results); } await writeFile(filePath, obj); @@ -85,7 +91,7 @@ async function queryResultTester(options) { set(obj, casePath + '.pipeline', pipeline); await writeFile(filePath, obj); } - if (!expectZeroResults) { + if (!expectZeroResults && !skipDbQuery) { assert(results.length); const expectedResults = get(obj, casePath + '.expectedResults'); assert.deepStrictEqual(results, expectedResults); diff --git a/test/utils/query-tester/types.ts b/test/utils/query-tester/types.ts index 1521b17..e24dd22 100644 --- a/test/utils/query-tester/types.ts +++ b/test/utils/query-tester/types.ts @@ -1,5 +1,5 @@ import {MongoClient, Document} from 'mongodb'; -import {PipelineFn, Schemas, ParserOptions} from '../../../lib/types'; +import {PipelineFn, ParserOptions} from '../../../lib/types'; /** Options to use when running the function to test/generate test outputs */ export interface BuildQueryResultOptions { @@ -26,6 +26,8 @@ export interface QueryResultOptions extends ParserOptions { ignoreDateValues?: boolean; /** Specifies if the pipeline should be written to the file, useful for debugging */ outputPipeline?: boolean; + /** If true the tester won't query the db, just generate the pipeline */ + skipDbQuery?: boolean; } export type AllQueryResultOptions = BuildQueryResultOptions &