diff --git a/src/main/java/generated/gov/cms/madie/simplexml/ClauseType.java b/src/main/java/generated/gov/cms/madie/simplexml/ClauseType.java index 9fd13b3..c55a7e8 100644 --- a/src/main/java/generated/gov/cms/madie/simplexml/ClauseType.java +++ b/src/main/java/generated/gov/cms/madie/simplexml/ClauseType.java @@ -26,6 +26,7 @@ * * * + * * * * @@ -44,6 +45,9 @@ public class ClauseType { protected CqldefinitionType cqldefinition; protected CqlaggfunctionType cqlaggfunction; + @XmlAttribute(name = "associatedPopulationUUID") + protected String associatedPopulationUUID; + @XmlAttribute(name = "displayName") protected String displayName; @@ -92,6 +96,24 @@ public void setCqlaggfunction(CqlaggfunctionType value) { this.cqlaggfunction = value; } + /** + * Gets the value of the associatedPopulationUUID property. + * + * @return possible object is {@link String } + */ + public String getAssociatedPopulationUUID() { + return associatedPopulationUUID; + } + + /** + * Sets the value of the associatedPopulationUUID property. + * + * @param value allowed object is {@link String } + */ + public void setAssociatedPopulationUUID(String value) { + this.associatedPopulationUUID = value; + } + /** * Gets the value of the displayName property. * diff --git a/src/main/java/gov/cms/madie/dto/CQLDefinition.java b/src/main/java/gov/cms/madie/dto/CQLDefinition.java index b87aff7..1ec5694 100644 --- a/src/main/java/gov/cms/madie/dto/CQLDefinition.java +++ b/src/main/java/gov/cms/madie/dto/CQLDefinition.java @@ -13,6 +13,7 @@ @NoArgsConstructor public class CQLDefinition { private String id; + private String uuid; private String definitionName; private String definitionLogic; private String context = "Patient"; diff --git a/src/main/java/gov/cms/madie/services/MeasureMapper.java b/src/main/java/gov/cms/madie/services/MeasureMapper.java index 9b8652e..1d30375 100644 --- a/src/main/java/gov/cms/madie/services/MeasureMapper.java +++ b/src/main/java/gov/cms/madie/services/MeasureMapper.java @@ -47,20 +47,28 @@ public interface MeasureMapper { @Mapping(target = "cqlLookUp", source = "cqlLookups") @Mapping(target = "measureDetails", source = "measure") - @Mapping(target = "measureGrouping", source = "measure") + @Mapping( + target = "measureGrouping", + expression = "java(measureToMeasureGroupingType(measure, cqlLookups))") @Mapping(target = "elementLookUp", source = "cqlLookups.elementLookups") - @Mapping(target = "supplementalDataElements", source = "measure.supplementalData") - @Mapping(target = "riskAdjustmentVariables", source = "measure.riskAdjustments") + @Mapping( + target = "supplementalDataElements", + expression = + "java(supplementalDataToSupplementalDataElementsType(measure.getSupplementalData(), cqlLookups.getDefinitions()))") + @Mapping( + target = "riskAdjustmentVariables", + expression = + "java(riskAdjustmentsToRiskAdjustmentVariablesType(measure.getRiskAdjustments(), cqlLookups.getDefinitions()))") @Mapping(target = "allUsedCQLLibs", source = "cqlLookups.includeLibraries") MeasureType measureToMeasureType(QdmMeasure measure, CqlLookups cqlLookups); - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") - @Mapping(target = "cqlUUID", expression = "java(measure.getMeasureSetId())") + @Mapping(target = "uuid", source = "versionId") + @Mapping(target = "cqlUUID", expression = "java(java.util.UUID.randomUUID().toString())") @Mapping(target = "title", source = "measureName") @Mapping(target = "measureModel", source = "model") @Mapping(target = "shortTitle", source = "ecqmTitle") @Mapping(target = "emeasureid", source = "cmsId") - @Mapping(target = "guid", source = "versionId") + @Mapping(target = "guid", source = "measureSetId") @Mapping( target = "cbeid", source = "measure.measureMetaData.endorsements", @@ -131,8 +139,10 @@ public interface MeasureMapper { @Mapping(target = "uuid", source = "measureSetId") QualityMeasureSetType measureToQualityMeasureSet(QdmMeasure measure); - default MeasureGroupingType measureToMeasureGroupingType(QdmMeasure measure) { - if (measure == null || CollectionUtils.isEmpty(measure.getGroups())) { + // measureGrouping mappings + default MeasureGroupingType measureToMeasureGroupingType( + QdmMeasure measure, CqlLookups cqlLookups) { + if (measure == null || CollectionUtils.isEmpty(measure.getGroups()) || cqlLookups == null) { return null; } @@ -142,74 +152,127 @@ default MeasureGroupingType measureToMeasureGroupingType(QdmMeasure measure) { .getGroup() .addAll( IntStream.range(0, groups.size()) - .mapToObj(i -> groupToGroupType(groups.get(i), i + 1)) + .mapToObj(i -> groupToGroupType(groups.get(i), i + 1, cqlLookups)) .toList()); return measureGroupingType; } @Mapping(target = "sequence", source = "sequence") - @Mapping(target = "clause", source = "group") + @Mapping(target = "clause", expression = "java(groupToClauseTypes(group, cqlLookups))") @Mapping(target = "ucum", source = "group.scoringUnit", qualifiedByName = "scoringUnitToUcum") - GroupType groupToGroupType(Group group, int sequence); + GroupType groupToGroupType(Group group, int sequence, CqlLookups cqlLookups); - default List groupToClauseTypes(Group group) { + default List groupToClauseTypes(Group group, CqlLookups cqlLookups) { if (group == null) { return null; } - + Set cqlDefinitions = cqlLookups.getDefinitions(); // Clauses are listed in the order Populations, Observations, Stratums List clauses = new ArrayList<>(); if (!CollectionUtils.isEmpty(group.getPopulations())) { - clauses.addAll(group.getPopulations().stream().map(this::populationToClauseType).toList()); + clauses.addAll( + group.getPopulations().stream() + .map( + population -> { + CQLDefinition cqlDefinition = + getCqlDefinition(population.getDefinition(), cqlDefinitions); + return populationToClauseType(population, cqlDefinition); + }) + .toList()); } if (!CollectionUtils.isEmpty(group.getMeasureObservations())) { clauses.addAll( - group.getMeasureObservations().stream().map(this::observationToClauseType).toList()); + group.getMeasureObservations().stream() + .map( + observation -> { + CQLDefinition cqlDefinition = + getCqlDefinition(observation.getDefinition(), cqlDefinitions); + String associatedPopulationUUID = ""; + if ("Ratio".equals(group.getScoring())) { + Population associatedPopulation = + group.getPopulations().stream() + .filter( + population -> + population.getId().equals(observation.getCriteriaReference())) + .findFirst() + .orElse(null); + associatedPopulationUUID = + associatedPopulation != null ? associatedPopulation.getId() : ""; + } + return observationToClauseType( + observation, cqlDefinition, associatedPopulationUUID); + }) + .toList()); } if (!CollectionUtils.isEmpty(group.getStratifications())) { clauses.addAll( - group.getStratifications().stream().map(this::stratificationToClauseType).toList()); + group.getStratifications().stream() + .map( + stratification -> { + CQLDefinition cqlDefinition = + getCqlDefinition(stratification.getCqlDefinition(), cqlDefinitions); + return stratificationToClauseType(stratification, cqlDefinition); + }) + .toList()); } return CollectionUtils.isEmpty(clauses) ? null : clauses; } + default CQLDefinition getCqlDefinition(String definition, Set cqlDefinitions) { + return cqlDefinitions.stream() + .filter(cqlDefinition -> definition.equals(cqlDefinition.getDefinitionName())) + .findFirst() + .orElse(null); + } + + // population mappings @Mapping( target = "isInGrouping", expression = "java(String.valueOf(org.apache.commons.lang3.StringUtils.isNotBlank(population.getDefinition())))") - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") - @Mapping(target = "cqldefinition", source = "population") + @Mapping(target = "uuid", source = "population.id") + @Mapping( + target = "cqldefinition", + expression = "java(populationToCqlDefinition(population, cqlDefinition))") @Mapping( target = "type", expression = "java(gov.cms.madie.util.MappingUtil.getPopulationType(population.getName()))") @Mapping(target = "displayName", expression = "java(population.getName().getDisplay())") - ClauseType populationToClauseType(Population population); + ClauseType populationToClauseType(Population population, CQLDefinition cqlDefinition); - @Mapping(target = "displayName", source = "name.display") - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") - CqldefinitionType populationToCqlDefinition(Population population); + @Mapping(target = "displayName", source = "population.name.display") + @Mapping(target = "uuid", source = "cqlDefinition.uuid") + CqldefinitionType populationToCqlDefinition(Population population, CQLDefinition cqlDefinition); + // observation mappings @Mapping( target = "isInGrouping", expression = "java(String.valueOf(org.apache.commons.lang3.StringUtils.isNotBlank(observation.getDefinition())))") - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") + @Mapping(target = "uuid", source = "observation.id") @Mapping(target = "type", constant = "measureObservation") @Mapping(target = "displayName", constant = "Measure Observation") - @Mapping(target = "cqlaggfunction", source = "observation") - ClauseType observationToClauseType(MeasureObservation observation); - - @Mapping(target = "displayName", source = "aggregateMethod") - @Mapping(target = "cqlfunction", source = "observation") - CqlaggfunctionType observationToCqlAggFunction(MeasureObservation observation); + @Mapping(target = "associatedPopulationUUID", source = "associatedPopulationUUID") + @Mapping( + target = "cqlaggfunction", + expression = "java(observationToCqlAggFunction(observation, cqlDefinition))") + ClauseType observationToClauseType( + MeasureObservation observation, CQLDefinition cqlDefinition, String associatedPopulationUUID); - @Mapping(target = "displayName", source = "definition") - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") - CqlfunctionType observationToCqlFunction(MeasureObservation observation); + @Mapping(target = "displayName", source = "observation.aggregateMethod") + @Mapping( + target = "cqlfunction", + expression = "java(observationToCqlFunction(observation, cqlDefinition))") + CqlaggfunctionType observationToCqlAggFunction( + MeasureObservation observation, CQLDefinition cqlDefinition); - // TODO: map observation to definition/aggregate function + @Mapping(target = "displayName", source = "observation.definition") + @Mapping(target = "uuid", source = "cqlDefinition.uuid") + CqlfunctionType observationToCqlFunction( + MeasureObservation observation, CQLDefinition cqlDefinition); + // stratification mappings @Mapping( target = "isInGrouping", expression = @@ -217,7 +280,7 @@ default List groupToClauseTypes(Group group) { @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") @Mapping(target = "type", constant = "stratum") @Mapping(target = "displayName", constant = "stratum") - ClauseType stratificationToClauseType(Stratification stratification); + ClauseType stratificationToClauseType(Stratification stratification, CQLDefinition cqlDefinition); // TODO: map stratification to definition/aggregate function @@ -243,10 +306,15 @@ default String scoringUnitToUcum(Object scoringUnit) { ScoringType scoringToScoringType(String scoring); default SupplementalDataElementsType supplementalDataToSupplementalDataElementsType( - List supplementalData) { + List supplementalData, Set cqlDefinitions) { List defs = Optional.ofNullable(supplementalData).orElse(List.of()).stream() - .map(this::defDescPairToCqldefinitionType) + .map( + sde -> { + CQLDefinition cqlDefinition = + getCqlDefinition(sde.getDefinition(), cqlDefinitions); + return defDescPairToCqldefinitionType(sde, cqlDefinition); + }) .toList(); SupplementalDataElementsType supplementalDataElementsType = new SupplementalDataElementsType(); supplementalDataElementsType.getCqldefinition().addAll(defs); @@ -274,10 +342,15 @@ default ElementLookUpType elementLookupsToElementLookupType(Set e QdmType elementLookupToQdmType(ElementLookup elementLookup); default RiskAdjustmentVariablesType riskAdjustmentsToRiskAdjustmentVariablesType( - List riskAdjustments) { + List riskAdjustments, Set cqlDefinitions) { List defs = Optional.ofNullable(riskAdjustments).orElse(List.of()).stream() - .map(this::defDescPairToCqldefinitionType) + .map( + rav -> { + CQLDefinition cqlDefinition = + getCqlDefinition(rav.getDefinition(), cqlDefinitions); + return defDescPairToCqldefinitionType(rav, cqlDefinition); + }) .toList(); RiskAdjustmentVariablesType riskAdjustmentVariablesType = new RiskAdjustmentVariablesType(); riskAdjustmentVariablesType.getCqldefinition().addAll(defs); @@ -338,9 +411,10 @@ default EndorsementType endorsementsToEndorsementType(List endorsem @Mapping(target = "id", source = "organization.oid") DeveloperType organizationToDeveloperType(Organization organization); - @Mapping(target = "displayName", source = "definition") - @Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())") - CqldefinitionType defDescPairToCqldefinitionType(DefDescPair defDescPair); + @Mapping(target = "displayName", source = "defDescPair.definition") + @Mapping(target = "uuid", source = "definition.uuid") + CqldefinitionType defDescPairToCqldefinitionType( + DefDescPair defDescPair, CQLDefinition definition); default TypesType baseConfigurationTypesToTypesTypes( List baseConfigurationTypes) { @@ -502,11 +576,12 @@ default FunctionsType cqlDefinitionsToFunctionsType(Set cqlDefini List cqlDefinitionsToFunctionTypes(Set cqlDefinitions); - @Mapping(target = "id", expression = "java(java.util.UUID.randomUUID().toString())") + @Mapping(target = "id", source = "uuid") @Mapping(target = "name", source = "definitionName") @Mapping(target = "logic", source = "definitionLogic") DefinitionType cqlDefinitionToDefinitionType(CQLDefinition cqlDefinition); + @Mapping(target = "id", source = "uuid") @Mapping(target = "logic", source = "definitionLogic") @Mapping(target = "name", source = "definitionName") @Mapping(target = "arguments", source = "functionArguments") diff --git a/src/main/resources/schemas/SimpleXML-QDM-5-6.xsd b/src/main/resources/schemas/SimpleXML-QDM-5-6.xsd index 742152c..ed1df47 100644 --- a/src/main/resources/schemas/SimpleXML-QDM-5-6.xsd +++ b/src/main/resources/schemas/SimpleXML-QDM-5-6.xsd @@ -185,6 +185,7 @@ + diff --git a/src/main/resources/xsl/qdm_v5_6_measure_details.xsl b/src/main/resources/xsl/qdm_v5_6_measure_details.xsl index c6792f4..792ba8b 100644 --- a/src/main/resources/xsl/qdm_v5_6_measure_details.xsl +++ b/src/main/resources/xsl/qdm_v5_6_measure_details.xsl @@ -192,17 +192,17 @@ + value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.cql"/> + value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.xml"/> + value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.json"/> - @@ -214,17 +214,17 @@ + value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.cql"/> + value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.xml"/> + value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.json"/> - @@ -884,7 +884,7 @@ - + diff --git a/src/test/java/gov/cms/madie/services/MeasureMapperTest.java b/src/test/java/gov/cms/madie/services/MeasureMapperTest.java index 9ddf4f2..73c1c55 100644 --- a/src/test/java/gov/cms/madie/services/MeasureMapperTest.java +++ b/src/test/java/gov/cms/madie/services/MeasureMapperTest.java @@ -1,5 +1,6 @@ package gov.cms.madie.services; +import generated.gov.cms.madie.simplexml.ClauseType; import generated.gov.cms.madie.simplexml.DevelopersType; import generated.gov.cms.madie.simplexml.EndorsementType; import generated.gov.cms.madie.simplexml.FinalizedDateType; @@ -11,6 +12,7 @@ import generated.gov.cms.madie.simplexml.ScoringType; import generated.gov.cms.madie.simplexml.StewardType; import generated.gov.cms.madie.simplexml.TypesType; +import gov.cms.madie.dto.CQLDefinition; import gov.cms.madie.dto.CqlLookups; import gov.cms.madie.models.common.ModelType; import gov.cms.madie.models.common.Organization; @@ -24,6 +26,8 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.UUID; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @@ -58,8 +62,8 @@ void testMeasureToMeasureType() { .improvementNotation("Improvement Notation") .supplementalData( List.of( - DefDescPair.builder().description("sde1").description("first SDE").build(), - DefDescPair.builder().description("sde2").description("second SDE").build())) + DefDescPair.builder().definition("sde1").description("first SDE").build(), + DefDescPair.builder().definition("sde2").description("second SDE").build())) .measureMetaData( MeasureMetaData.builder() .description("Measure Description") @@ -88,7 +92,21 @@ void testMeasureToMeasureType() { .build()) .build(); - CqlLookups cqlLookups = CqlLookups.builder().build(); + CqlLookups cqlLookups = + CqlLookups.builder() + .definitions( + Set.of( + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .uuid(UUID.randomUUID().toString()) + .definitionName("sde1") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .uuid(UUID.randomUUID().toString()) + .definitionName("sde2") + .build())) + .build(); MeasureType output = measureMapper.measureToMeasureType(measure, cqlLookups); assertThat(output, is(notNullValue())); @@ -176,8 +194,16 @@ void measureToMeasureDetailsType() { } @Test - void testMeasureToMeasureGroupingTypeReturnsNullForNullInput() { - MeasureGroupingType output = measureMapper.measureToMeasureGroupingType(null); + void testMeasureToMeasureGroupingTypeReturnsNullForNullMeasure() { + MeasureGroupingType output = + measureMapper.measureToMeasureGroupingType(null, CqlLookups.builder().build()); + assertThat(output, is(nullValue())); + } + + @Test + void testMeasureToMeasureGroupingTypeReturnsNullForNullLookups() { + MeasureGroupingType output = + measureMapper.measureToMeasureGroupingType(QdmMeasure.builder().build(), null); assertThat(output, is(nullValue())); } @@ -185,14 +211,16 @@ void testMeasureToMeasureGroupingTypeReturnsNullForNullInput() { void testMeasureToMeasureGroupingTypeReturnsNullForNullGroupsInput() { QdmMeasure measure = new QdmMeasure(); measure.setGroups(null); - MeasureGroupingType output = measureMapper.measureToMeasureGroupingType(measure); + MeasureGroupingType output = + measureMapper.measureToMeasureGroupingType(measure, CqlLookups.builder().build()); assertThat(output, is(nullValue())); } @Test void testMeasureToMeasureGroupingTypeReturnsNullForEmptyGroupsInput() { QdmMeasure measure = QdmMeasure.builder().groups(List.of()).build(); - MeasureGroupingType output = measureMapper.measureToMeasureGroupingType(measure); + MeasureGroupingType output = + measureMapper.measureToMeasureGroupingType(measure, CqlLookups.builder().build()); assertThat(output, is(nullValue())); } @@ -268,7 +296,24 @@ void testMeasureToMeasureGroupingTypeReturnsNullForSingleGroupInput() { .build())) .build())) .build(); - MeasureGroupingType output = measureMapper.measureToMeasureGroupingType(measure); + CqlLookups cqlLookups = + CqlLookups.builder() + .definitions( + Set.of( + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("ipp") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("denom") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("numer") + .build())) + .build(); + MeasureGroupingType output = measureMapper.measureToMeasureGroupingType(measure, cqlLookups); assertThat(output, is(notNullValue())); assertThat(output.getGroup(), is(notNullValue())); assertThat(output.getGroup().size(), is(equalTo(1))); @@ -577,4 +622,148 @@ void testScoringUnitToUcumReturnsNullForMapMissing() { String output = measureMapper.scoringUnitToUcum(scoringUnit); assertThat(output, is(nullValue())); } + + @Test + void testGroupToClauseTypesForCvGroup() { + Group group = + Group.builder() + .scoring(MeasureScoring.CONTINUOUS_VARIABLE.toString()) + .populations( + List.of( + Population.builder() + .id("id1") + .name(PopulationType.INITIAL_POPULATION) + .definition("Initial Population") + .description("the IP description") + .build(), + Population.builder() + .id("id2") + .name(PopulationType.MEASURE_POPULATION) + .definition("Measure Population") + .description("the denom description") + .build(), + Population.builder() + .id("id3") + .name(PopulationType.MEASURE_POPULATION_EXCLUSION) + .definition("") + .description("") + .build())) + .measureObservations( + List.of( + MeasureObservation.builder() + .id("obs1") + .definition("Measure Observations") + .criteriaReference("id2") + .aggregateMethod("Average") + .build())) + .build(); + + CqlLookups cqlLookups = + CqlLookups.builder() + .definitions( + Set.of( + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Initial Population") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Measure Population") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Measure Observations") + .build())) + .build(); + + List clauses = measureMapper.groupToClauseTypes(group, cqlLookups); + assertThat(clauses.size(), is(equalTo(4))); + ClauseType observationType = clauses.get(3); + assertThat(observationType.getType(), is(equalTo("measureObservation"))); + assertThat(observationType.getAssociatedPopulationUUID(), is(equalTo(""))); + assertThat(observationType.getCqlaggfunction(), is(notNullValue())); + } + + @Test + void testGroupToClauseTypesForRatioGroup() { + Population denominator = + Population.builder() + .id("id2") + .name(PopulationType.DENOMINATOR) + .definition("Denominator") + .description("the denom description") + .build(); + Population numerator = + Population.builder() + .id("id3") + .name(PopulationType.NUMERATOR) + .definition("Numerator") + .description("") + .build(); + Group group = + Group.builder() + .scoring(MeasureScoring.RATIO.toString()) + .populations( + List.of( + Population.builder() + .id("id1") + .name(PopulationType.INITIAL_POPULATION) + .definition("Initial Population") + .description("the IP description") + .build(), + denominator, + numerator)) + .measureObservations( + List.of( + MeasureObservation.builder() + .id("obs1") + .definition("Denominator Observations") + .criteriaReference("id2") + .aggregateMethod("Average") + .build(), + MeasureObservation.builder() + .id("obs1") + .definition("Numerator Observations") + .criteriaReference("id3") + .aggregateMethod("Average") + .build())) + .build(); + + CqlLookups cqlLookups = + CqlLookups.builder() + .definitions( + Set.of( + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Initial Population") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Denominator") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Numerator") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Denominator Observations") + .build(), + CQLDefinition.builder() + .id(UUID.randomUUID().toString()) + .definitionName("Numerator Observations") + .build())) + .build(); + + List clauses = measureMapper.groupToClauseTypes(group, cqlLookups); + assertThat(clauses.size(), is(equalTo(5))); + ClauseType denomObservationType = clauses.get(3); + assertThat(denomObservationType.getType(), is(equalTo("measureObservation"))); + assertThat( + denomObservationType.getAssociatedPopulationUUID(), is(equalTo(denominator.getId()))); + + ClauseType numerObservationType = clauses.get(4); + assertThat(numerObservationType.getType(), is(equalTo("measureObservation"))); + assertThat(numerObservationType.getAssociatedPopulationUUID(), is(equalTo(numerator.getId()))); + } }