diff --git a/dist/browser.js b/dist/browser.js index 12db5ad..a735a8c 100644 --- a/dist/browser.js +++ b/dist/browser.js @@ -687,8 +687,8 @@ module.exports = class MeasureHelpers { ) { return localIds; } - // Stop recursing if this node represents the Patient obj since it is not part of coverage consideration. - if (statement?.name === "Patient") return localIds; + // Stop recursing if this node represents the Patient obj since it is not part of coverage consideration. + if (statement.name && statement.name === 'Patient') return localIds; // looking at the key and value of everything on this object or array for (const k in statement) { @@ -874,11 +874,18 @@ module.exports = class MeasureHelpers { localId: statement.localId, isFalsyLiteral: true, }; - // else if the key is localId, push the value + // else if the key is localId, push the value } else if (k === 'localId') { + // skip IsNulls that immediately follow a Not operator so that users don't have to cover "null" when "not null" is covered. + if (statement.type && statement.type === 'IsNull' + && typeof parentNode === 'object' + && parentNode.type && parentNode.type === "Not") { + continue; // skip the localId on this node. + } localIds[v] = { localId: v }; // if the value is an array or object, recurse - } else if (Array.isArray(v) || (typeof v === 'object' && k !== "codes")) { + } else if (Array.isArray(v) + || (typeof v === 'object' && k !== 'codes')) { this.findAllLocalIdsInStatement( v, libraryName, diff --git a/dist/browser.js-e b/dist/browser.js-e index 54715e8..fb55414 100644 --- a/dist/browser.js-e +++ b/dist/browser.js-e @@ -687,8 +687,8 @@ module.exports = class MeasureHelpers { ) { return localIds; } - // Stop recursing if this node represents the Patient obj since it is not part of coverage consideration. - if (statement?.name === "Patient") return localIds; + // Stop recursing if this node represents the Patient obj since it is not part of coverage consideration. + if (statement.name && statement.name === 'Patient') return localIds; // looking at the key and value of everything on this object or array for (const k in statement) { @@ -874,11 +874,18 @@ module.exports = class MeasureHelpers { localId: statement.localId, isFalsyLiteral: true, }; - // else if the key is localId, push the value + // else if the key is localId, push the value } else if (k === 'localId') { + // skip IsNulls that immediately follow a Not operator so that users don't have to cover "null" when "not null" is covered. + if (statement.type && statement.type === 'IsNull' + && typeof parentNode === 'object' + && parentNode.type && parentNode.type === "Not") { + continue; // skip the localId on this node. + } localIds[v] = { localId: v }; // if the value is an array or object, recurse - } else if (Array.isArray(v) || (typeof v === 'object' && k !== "codes")) { + } else if (Array.isArray(v) + || (typeof v === 'object' && k !== 'codes')) { this.findAllLocalIdsInStatement( v, libraryName, diff --git a/lib/helpers/measure_helpers.js b/lib/helpers/measure_helpers.js index 8f295c7..c8096d5 100644 --- a/lib/helpers/measure_helpers.js +++ b/lib/helpers/measure_helpers.js @@ -327,8 +327,15 @@ module.exports = class MeasureHelpers { localId: statement.localId, isFalsyLiteral: true, }; - // else if the key is localId, push the value + // else if the key is localId, push the value } else if (k === 'localId') { + // skip IsNulls that immediately follow a Not operator so that users don't have to cover "null" when "not null" is covered. + if (statement.type && statement.type === 'IsNull' + && typeof parentNode === 'object' + && parentNode.type && parentNode.type === 'Not') { + // eslint-disable-next-line + continue; // skip the localId on this node. + } localIds[v] = { localId: v }; // if the value is an array or object, recurse } else if (Array.isArray(v) diff --git a/package.json b/package.json index 8367a2e..2b5971d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cqm-execution", - "version": "4.2.2", + "version": "4.2.3", "description": "NPM module for calculating eCQMs (electronic clinical quality measures) written in CQL (clinical quality language).", "main": "lib/index.js", "scripts": {