From f0a99617002e4de669a78984fdaae93fb54f8e4b Mon Sep 17 00:00:00 2001 From: Chris Hossenlopp Date: Tue, 22 Oct 2024 16:43:08 -0400 Subject: [PATCH 1/6] Initial incomplete fix for relationship alias coverage --- src/calculation/HTMLBuilder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calculation/HTMLBuilder.ts b/src/calculation/HTMLBuilder.ts index ef1a81c7..caef87dc 100644 --- a/src/calculation/HTMLBuilder.ts +++ b/src/calculation/HTMLBuilder.ts @@ -84,11 +84,11 @@ Handlebars.registerHelper('highlightCoverage', (localId, context) => { const libraryName: string = context.data.root.libraryName; const clauseResults: ClauseResult[] = context.data.root.clauseResults; - const clauseResult = clauseResults.filter(result => result.libraryName === libraryName && result.localId === localId); + const clauseResult = clauseResults.find(result => result.libraryName === libraryName && result.localId === localId); if (clauseResult) { - if (clauseResult.some(c => c.final === FinalResult.TRUE)) { + if (clauseResult.final === FinalResult.TRUE) { return objToCSS(cqlLogicClauseCoveredStyle); - } else if (clauseResult.every(c => c.final === FinalResult.FALSE || c.final === FinalResult.UNHIT)) { + } else if (clauseResult.final === FinalResult.FALSE || clauseResult.final === FinalResult.UNHIT) { return objToCSS(cqlLogicUncoveredClauseStyle); } } From a871fc09be20f2b963bf04381acd9243b7d2e254 Mon Sep 17 00:00:00 2001 From: Chris Hossenlopp Date: Mon, 28 Oct 2024 14:34:47 -0400 Subject: [PATCH 2/6] Added code to clause results helpers to find the relationship expression alias id in annotation structure, replacing old +1 hack --- src/helpers/ClauseResultsHelpers.ts | 87 +++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/src/helpers/ClauseResultsHelpers.ts b/src/helpers/ClauseResultsHelpers.ts index f53de0cd..50c4c1a0 100644 --- a/src/helpers/ClauseResultsHelpers.ts +++ b/src/helpers/ClauseResultsHelpers.ts @@ -1,4 +1,4 @@ -import { ELMProperty } from '../types/ELMTypes'; +import { Annotation, AnnotationStatement, ELMProperty } from '../types/ELMTypes'; import { ELMFunctionRef } from '../types/ELMTypes'; import { ELM, ELMBinaryExpression, ELMStatement } from '../types/ELMTypes'; @@ -132,11 +132,16 @@ export function findAllLocalIdsInStatement( aliasMap[v] = statement.expression.localId; // Determine the localId for this alias. if (statement.localId) { - // Older translator versions require with statements to use the statement.expression.localId + 1 as the alias Id - // even if the statement already has a localId. There is not a clear mapping for alias with statements in the new - // translator, so they will go un highlighted but this will not affect coverage calculation + // There is not a clear mapping for `With` and `Without` relationship alias with statements in newer + // translator versions. The node in the annotation that contains the alias does has a local id that doesn't + // exist in the elm. We have to find this localId by looking for it in the annotation structure. if (statement.type === 'With' || statement.type === 'Without') { - alId = (parseInt(statement.expression.localId, 10) + 1).toString(); + if (annotation) { + const id = findRelationshipAliasAnnotationId(annotation, statement.expression.localId); + if (id) { + alId = id; + } + } } else { alId = statement.localId; } @@ -347,6 +352,78 @@ export function findLocalIdsForComparisonOperators( } } +/** + * Helper function to kick off the recursive search for the relationship (With, Without) source's localId in annotation + * structure. If found this returns the localId of the parent node of the given source localId. Null is returned if not + * found. + */ +function findRelationshipAliasAnnotationId(annotation: Annotation[], sourceLocalId: string): string | null { + for (const a of annotation) { + const id = findRelationshipAliasNodeAnnotationId([a.s], sourceLocalId); + if (id) { + return id; + } + } + return null; +} + +/** + * Recursively looks through the annotation structure for the source localId and grab its parent id which also contains + * the alias. This search is valid to be used with relationship (With, Without) clauses and allows us to tag the found + * localId, which only exists in the annotation, as the alias localId for the source so it can be highlighted when the + * source clause has a result. + * + * For example in the below snippet. We are looking for the source localId 355 and want to return 301 which includes + * the alias. + * + * { + * "r": "301", + * "s": [ + * { + * "r": "355", + * "s": [ + * { + * "s": [ + * { + * "value": [ + * "\"Bladder Cancer Diagnosis\"" + * ] + * } + * ] + * } + * ] + * }, + * { + * "value": [ + * " ", + * "BladderCancer" + * ] + * } + * ] + * } + * + * @returns id of the node that is parent to the source localId if found + */ +function findRelationshipAliasNodeAnnotationId( + annotation: AnnotationStatement[], + sourceLocalId: string +): string | null { + for (const as of annotation) { + // if this node has a list of more nodes in s, look at the first one and see if it matches the sourceLocalId + if (as.r && as.s && as.s[0]?.r === sourceLocalId) { + // return this localId which is the parent of the sourceLocalId + return as.r; + } else if (as.s) { + // otherwise, keep recursing and return the alias localId if found + const id = findRelationshipAliasNodeAnnotationId(as.s, sourceLocalId); + if (id) { + return id; + } + } + } + return null; +} + /** * Find the localId of the library reference in the JSON elm annotation. This recursively searches the annotation structure * for the clause of the library ref. When that is found it knows where to look inside of that for where the library From 335baf942da8eb0d4a93193e1b23018f9f090262 Mon Sep 17 00:00:00 2001 From: Chris Hossenlopp Date: Thu, 31 Oct 2024 12:55:25 -0400 Subject: [PATCH 3/6] reworked html generation tests to use input more reflective of actual usage --- test/unit/HTMLBuilder.test.ts | 72 ++++++++++++++----- .../html/simpleCoverageAnnotation.html | 10 +-- .../html/simpleCoverageAnnotation2.html | 34 ++++----- .../fixtures/html/simpleFalseAnnotation.html | 29 -------- .../fixtures/html/simpleTrueAnnotation.html | 8 +-- 5 files changed, 80 insertions(+), 73 deletions(-) delete mode 100644 test/unit/fixtures/html/simpleFalseAnnotation.html diff --git a/test/unit/HTMLBuilder.test.ts b/test/unit/HTMLBuilder.test.ts index 5d933a45..1ae91982 100644 --- a/test/unit/HTMLBuilder.test.ts +++ b/test/unit/HTMLBuilder.test.ts @@ -24,7 +24,7 @@ describe('HTMLBuilder', () => { let statementResults: StatementResult[]; let trueClauseResults: ClauseResult[]; let falseClauseResults: ClauseResult[]; - const desiredLocalId = '119'; + const defineStatementLocalId = '119'; const trueStyleString = objToCSS(cqlLogicClauseTrueStyle); const falseStyleString = objToCSS(cqlLogicClauseFalseStyle); const coverageStyleString = objToCSS(cqlLogicClauseCoveredStyle); @@ -114,15 +114,16 @@ describe('HTMLBuilder', () => { beforeEach(() => { elm = getELMFixture('elm/CMS723v0.json'); - simpleExpression = elm.library.statements.def.find(d => d.localId === desiredLocalId); // Simple expression for Denominator + simpleExpression = elm.library.statements.def.find(d => d.localId === defineStatementLocalId); // Simple expression for Denominator + // statementResults = [ { statementName: simpleExpression?.name ?? '', libraryName: elm.library.identifier.id, final: FinalResult.TRUE, relevance: Relevance.TRUE, - localId: desiredLocalId + localId: defineStatementLocalId } ]; @@ -130,9 +131,30 @@ describe('HTMLBuilder', () => { { statementName: simpleExpression?.name ?? '', libraryName: elm.library.identifier.id, - localId: desiredLocalId, + localId: defineStatementLocalId, final: FinalResult.TRUE, raw: true + }, + { + statementName: simpleExpression?.name ?? '', + libraryName: elm.library.identifier.id, + localId: '118', + final: FinalResult.TRUE, + raw: [{ resourceType: 'foo' }] + }, + { + statementName: simpleExpression?.name ?? '', + libraryName: elm.library.identifier.id, + localId: '116', + final: FinalResult.TRUE, + raw: [{ resourceType: 'foo' }] + }, + { + statementName: simpleExpression?.name ?? '', + libraryName: elm.library.identifier.id, + localId: '115', + final: FinalResult.TRUE, + raw: [{ resourceType: 'foo' }] } ]; @@ -140,28 +162,42 @@ describe('HTMLBuilder', () => { { statementName: simpleExpression?.name ?? '', libraryName: elm.library.identifier.id, - localId: desiredLocalId, + localId: defineStatementLocalId, final: FinalResult.FALSE, raw: false + }, + { + statementName: simpleExpression?.name ?? '', + libraryName: elm.library.identifier.id, + localId: '117', + final: FinalResult.FALSE, + raw: [] } + // specifically not including this result to make this clause have no coverage styling. + // This simulates a clause that only exists in the annotation. + // { + // statementName: simpleExpression?.name ?? '', + // libraryName: elm.library.identifier.id, + // localId: '101', + // final: FinalResult.FALSE, + // raw: [] + // } ]; }); - test('simple HTML with generation with true clause', () => { + test('simple HTML with generation with mix of false and true clauses', () => { // Ignore tabs and new lines const expectedHTML = getHTMLFixture('simpleTrueAnnotation.html').replace(/\s/g, ''); - const res = generateHTML(simpleMeasure, [elm], statementResults, trueClauseResults, 'test'); + const res = generateHTML( + simpleMeasure, + [elm], + statementResults, + [...trueClauseResults, ...falseClauseResults], + 'test' + ); expect(res.replace(/\s/g, '')).toEqual(expectedHTML); expect(res.includes(trueStyleString)).toBeTruthy(); - }); - - test('simple HTML with generation with false clause', () => { - // Ignore tabs and new lines - const expectedHTML = getHTMLFixture('simpleFalseAnnotation.html').replace(/\s/g, ''); - const res = generateHTML(simpleMeasure, [elm], statementResults, falseClauseResults, 'test'); - - expect(res.replace(/\s/g, '')).toEqual(expectedHTML); expect(res.includes(falseStyleString)).toBeTruthy(); }); @@ -213,7 +249,7 @@ describe('HTMLBuilder', () => { detailedResults: [ { statementResults: statementResults, - clauseResults: [trueClauseResults[0], falseClauseResults[0]], + clauseResults: [...trueClauseResults, ...falseClauseResults], groupId: 'test' } ] @@ -235,12 +271,12 @@ describe('HTMLBuilder', () => { detailedResults: [ { statementResults: statementResults, - clauseResults: [trueClauseResults[0], falseClauseResults[0]], + clauseResults: [...trueClauseResults, ...falseClauseResults], groupId: 'test' }, { statementResults: statementResults, - clauseResults: [trueClauseResults[0], falseClauseResults[0]], + clauseResults: [...trueClauseResults, ...falseClauseResults], groupId: 'test2' } ] diff --git a/test/unit/fixtures/html/simpleCoverageAnnotation.html b/test/unit/fixtures/html/simpleCoverageAnnotation.html index 8b46bd65..2aee805a 100644 --- a/test/unit/fixtures/html/simpleCoverageAnnotation.html +++ b/test/unit/fixtures/html/simpleCoverageAnnotation.html @@ -1,5 +1,5 @@
-

test Clause Coverage: 100%

+

test Clause Coverage: 80.0%

test Clause Coverage: 100%
       
         
           define "Denominator": 
-          
-            
-              
+          
+            
+              
                 "Encounter with Atrial Ablation Procedure"
               
               union
-              
+              
                 "History of Atrial FibrillationFlutter"
               
             
diff --git a/test/unit/fixtures/html/simpleCoverageAnnotation2.html b/test/unit/fixtures/html/simpleCoverageAnnotation2.html
index 7d4f528c..92caa2fa 100644
--- a/test/unit/fixtures/html/simpleCoverageAnnotation2.html
+++ b/test/unit/fixtures/html/simpleCoverageAnnotation2.html
@@ -1,29 +1,29 @@
 
-

test2 Clause Coverage: 100%

+

test2 Clause Coverage: 80.0%

-        
-          
-            define "Denominator": 
-            
-              
-                
-                  "Encounter with Atrial Ablation Procedure"
-                
-                union
-                
-                  "History of Atrial FibrillationFlutter"
-                
+      
+        
+          define "Denominator": 
+          
+            
+              
+                "Encounter with Atrial Ablation Procedure"
               
               union
-              
-                "Current Diagnosis Atrial FibrillationFlutter"
+              
+                "History of Atrial FibrillationFlutter"
               
             
+            union
+            
+              "Current Diagnosis Atrial FibrillationFlutter"
+            
           
-        
-      
+ + +
diff --git a/test/unit/fixtures/html/simpleFalseAnnotation.html b/test/unit/fixtures/html/simpleFalseAnnotation.html deleted file mode 100644 index cf1d4bb5..00000000 --- a/test/unit/fixtures/html/simpleFalseAnnotation.html +++ /dev/null @@ -1,29 +0,0 @@ -
-

Population Group: test

-
-    
-      
-        define "Denominator": 
-        
-          
-            
-              "Encounter with Atrial Ablation Procedure"
-            
-            union
-            
-              "History of Atrial FibrillationFlutter"
-            
-          
-          union
-          
-            "Current Diagnosis Atrial FibrillationFlutter"
-          
-        
-      
-    
-  
-
diff --git a/test/unit/fixtures/html/simpleTrueAnnotation.html b/test/unit/fixtures/html/simpleTrueAnnotation.html index f1b616eb..dc60f846 100644 --- a/test/unit/fixtures/html/simpleTrueAnnotation.html +++ b/test/unit/fixtures/html/simpleTrueAnnotation.html @@ -8,18 +8,18 @@

Population Group: test

define "Denominator": - - + + "Encounter with Atrial Ablation Procedure" union - + "History of Atrial FibrillationFlutter" union - + "Current Diagnosis Atrial FibrillationFlutter" From c052ea36725270727779d327d2b0de4ed823bc79 Mon Sep 17 00:00:00 2001 From: lmd59 Date: Thu, 31 Oct 2024 15:18:40 -0400 Subject: [PATCH 4/6] Update comments for clarity --- src/helpers/ClauseResultsHelpers.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/helpers/ClauseResultsHelpers.ts b/src/helpers/ClauseResultsHelpers.ts index 50c4c1a0..edceb13b 100644 --- a/src/helpers/ClauseResultsHelpers.ts +++ b/src/helpers/ClauseResultsHelpers.ts @@ -132,8 +132,8 @@ export function findAllLocalIdsInStatement( aliasMap[v] = statement.expression.localId; // Determine the localId for this alias. if (statement.localId) { - // There is not a clear mapping for `With` and `Without` relationship alias with statements in newer - // translator versions. The node in the annotation that contains the alias does has a local id that doesn't + // There is not a clear mapping for `With` and `Without` relationship aliases with statements in newer + // translator versions. The node in the annotation that contains the alias has a local id that doesn't // exist in the elm. We have to find this localId by looking for it in the annotation structure. if (statement.type === 'With' || statement.type === 'Without') { if (annotation) { @@ -353,7 +353,7 @@ export function findLocalIdsForComparisonOperators( } /** - * Helper function to kick off the recursive search for the relationship (With, Without) source's localId in annotation + * Helper function to kick off the recursive search for the relationship (With, Without) source's localId in the annotation * structure. If found this returns the localId of the parent node of the given source localId. Null is returned if not * found. */ @@ -368,8 +368,8 @@ function findRelationshipAliasAnnotationId(annotation: Annotation[], sourceLocal } /** - * Recursively looks through the annotation structure for the source localId and grab its parent id which also contains - * the alias. This search is valid to be used with relationship (With, Without) clauses and allows us to tag the found + * Recursively looks through the annotation structure for the source localId and grabs its parent id which also contains + * the alias. This search is valid to be used with relationship (With, Without) clauses and allows us to tag the found * localId, which only exists in the annotation, as the alias localId for the source so it can be highlighted when the * source clause has a result. * From cf8fbda40e90f1181adc332c365f7a9ab2772f25 Mon Sep 17 00:00:00 2001 From: LaurenD Date: Thu, 31 Oct 2024 15:27:04 -0400 Subject: [PATCH 5/6] Check for undefined alias id and update iterator variable --- src/helpers/ClauseResultsHelpers.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/helpers/ClauseResultsHelpers.ts b/src/helpers/ClauseResultsHelpers.ts index edceb13b..03bd40c1 100644 --- a/src/helpers/ClauseResultsHelpers.ts +++ b/src/helpers/ClauseResultsHelpers.ts @@ -33,7 +33,7 @@ export function findLocalIdsInStatementByName(libraryElm: ELM, statementName: st for (const alias of Array.from(emptyResultClauses)) { // Only do it if we have a clause for where the result should be fetched from // and have a localId for the clause that the result should map to - if (localIds[alias.expressionLocalId] != null && alias.aliasLocalId != null) { + if (localIds[alias.expressionLocalId] != null && alias.aliasLocalId) { localIds[alias.aliasLocalId] = { localId: alias.aliasLocalId, sourceLocalId: alias.expressionLocalId @@ -408,14 +408,14 @@ function findRelationshipAliasNodeAnnotationId( annotation: AnnotationStatement[], sourceLocalId: string ): string | null { - for (const as of annotation) { + for (const node of annotation) { // if this node has a list of more nodes in s, look at the first one and see if it matches the sourceLocalId - if (as.r && as.s && as.s[0]?.r === sourceLocalId) { + if (node.r && node.s && node.s[0]?.r === sourceLocalId) { // return this localId which is the parent of the sourceLocalId - return as.r; - } else if (as.s) { + return node.r; + } else if (node.s) { // otherwise, keep recursing and return the alias localId if found - const id = findRelationshipAliasNodeAnnotationId(as.s, sourceLocalId); + const id = findRelationshipAliasNodeAnnotationId(node.s, sourceLocalId); if (id) { return id; } From 5769ba78d9a3bdf121e338343e5c202732d0634e Mon Sep 17 00:00:00 2001 From: Chris Hossenlopp Date: Thu, 31 Oct 2024 15:57:50 -0400 Subject: [PATCH 6/6] Added UNHIT results to the HTMLBuilder Tests --- test/unit/HTMLBuilder.test.ts | 47 +++++++++++++------ .../html/simpleCoverageAnnotation.html | 9 +++- .../html/simpleCoverageAnnotation2.html | 9 +++- ...html => simpleHighlightingAnnotation.html} | 8 ++++ 4 files changed, 56 insertions(+), 17 deletions(-) rename test/unit/fixtures/html/{simpleTrueAnnotation.html => simpleHighlightingAnnotation.html} (56%) diff --git a/test/unit/HTMLBuilder.test.ts b/test/unit/HTMLBuilder.test.ts index 1ae91982..8d98cfd1 100644 --- a/test/unit/HTMLBuilder.test.ts +++ b/test/unit/HTMLBuilder.test.ts @@ -20,11 +20,13 @@ import { getELMFixture, getHTMLFixture, getJSONFixture } from './helpers/testHel describe('HTMLBuilder', () => { let elm = {}; - let simpleExpression: ELMStatement | undefined; + let denominatorExpression: ELMStatement | undefined; + let numeratorExpression: ELMStatement | undefined; let statementResults: StatementResult[]; let trueClauseResults: ClauseResult[]; let falseClauseResults: ClauseResult[]; - const defineStatementLocalId = '119'; + const denominatorLocalId = '119'; + const numeratorLocalId = '135'; const trueStyleString = objToCSS(cqlLogicClauseTrueStyle); const falseStyleString = objToCSS(cqlLogicClauseFalseStyle); const coverageStyleString = objToCSS(cqlLogicClauseCoveredStyle); @@ -114,43 +116,51 @@ describe('HTMLBuilder', () => { beforeEach(() => { elm = getELMFixture('elm/CMS723v0.json'); - simpleExpression = elm.library.statements.def.find(d => d.localId === defineStatementLocalId); // Simple expression for Denominator + denominatorExpression = elm.library.statements.def.find(d => d.localId === denominatorLocalId); // Simple expression for Denominator + numeratorExpression = elm.library.statements.def.find(d => d.localId === numeratorLocalId); // Simple expression for Denominator // statementResults = [ { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, final: FinalResult.TRUE, relevance: Relevance.TRUE, - localId: defineStatementLocalId + localId: denominatorLocalId + }, + { + statementName: numeratorExpression?.name ?? '', + libraryName: elm.library.identifier.id, + final: FinalResult.UNHIT, + relevance: Relevance.FALSE, + localId: numeratorLocalId } ]; trueClauseResults = [ { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, - localId: defineStatementLocalId, + localId: denominatorLocalId, final: FinalResult.TRUE, raw: true }, { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, localId: '118', final: FinalResult.TRUE, raw: [{ resourceType: 'foo' }] }, { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, localId: '116', final: FinalResult.TRUE, raw: [{ resourceType: 'foo' }] }, { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, localId: '115', final: FinalResult.TRUE, @@ -160,19 +170,19 @@ describe('HTMLBuilder', () => { falseClauseResults = [ { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, - localId: defineStatementLocalId, + localId: denominatorLocalId, final: FinalResult.FALSE, raw: false }, { - statementName: simpleExpression?.name ?? '', + statementName: denominatorExpression?.name ?? '', libraryName: elm.library.identifier.id, localId: '117', final: FinalResult.FALSE, raw: [] - } + }, // specifically not including this result to make this clause have no coverage styling. // This simulates a clause that only exists in the annotation. // { @@ -182,12 +192,19 @@ describe('HTMLBuilder', () => { // final: FinalResult.FALSE, // raw: [] // } + { + statementName: numeratorExpression?.name ?? '', + libraryName: elm.library.identifier.id, + localId: numeratorLocalId, + final: FinalResult.UNHIT, + raw: false + } ]; }); test('simple HTML with generation with mix of false and true clauses', () => { // Ignore tabs and new lines - const expectedHTML = getHTMLFixture('simpleTrueAnnotation.html').replace(/\s/g, ''); + const expectedHTML = getHTMLFixture('simpleHighlightingAnnotation.html').replace(/\s/g, ''); const res = generateHTML( simpleMeasure, [elm], diff --git a/test/unit/fixtures/html/simpleCoverageAnnotation.html b/test/unit/fixtures/html/simpleCoverageAnnotation.html index 2aee805a..855ae6c1 100644 --- a/test/unit/fixtures/html/simpleCoverageAnnotation.html +++ b/test/unit/fixtures/html/simpleCoverageAnnotation.html @@ -1,5 +1,5 @@
-

test Clause Coverage: 80.0%

+

test Clause Coverage: 66.7%

test Clause Coverage: 80.0%
         
       
     
+
+    
+    define "Numerator": "Denominator" NonElectiveEncounter
+        with "Anticoagulant Therapy at Discharge" Anticoagulant
+            such that Anticoagulant.authorDatetime during NonElectiveEncounter.relevantPeriod
+    
diff --git a/test/unit/fixtures/html/simpleCoverageAnnotation2.html b/test/unit/fixtures/html/simpleCoverageAnnotation2.html index 92caa2fa..c76fb7bb 100644 --- a/test/unit/fixtures/html/simpleCoverageAnnotation2.html +++ b/test/unit/fixtures/html/simpleCoverageAnnotation2.html @@ -1,5 +1,5 @@
-

test2 Clause Coverage: 80.0%

+

test2 Clause Coverage: 66.7%

test2 Clause Coverage: 80.0%
         
       
     
+
+    
+    define "Numerator": "Denominator" NonElectiveEncounter
+        with "Anticoagulant Therapy at Discharge" Anticoagulant
+            such that Anticoagulant.authorDatetime during NonElectiveEncounter.relevantPeriod
+    
diff --git a/test/unit/fixtures/html/simpleTrueAnnotation.html b/test/unit/fixtures/html/simpleHighlightingAnnotation.html similarity index 56% rename from test/unit/fixtures/html/simpleTrueAnnotation.html rename to test/unit/fixtures/html/simpleHighlightingAnnotation.html index dc60f846..034e8806 100644 --- a/test/unit/fixtures/html/simpleTrueAnnotation.html +++ b/test/unit/fixtures/html/simpleHighlightingAnnotation.html @@ -26,4 +26,12 @@

Population Group: test

+ +
+  
+  define "Numerator": "Denominator" NonElectiveEncounter
+      with "Anticoagulant Therapy at Discharge" Anticoagulant
+          such that Anticoagulant.authorDatetime during NonElectiveEncounter.relevantPeriod
+