add narrative generation tests
This commit is contained in:
parent
1fb2da565b
commit
e6ecc998ea
|
@ -23,7 +23,9 @@ package org.hl7.fhir.r5.terminologies;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
@ -47,6 +49,90 @@ import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
public class CodeSystemUtilities {
|
public class CodeSystemUtilities {
|
||||||
|
|
||||||
|
public static class CodeSystemNavigator {
|
||||||
|
|
||||||
|
private CodeSystem cs;
|
||||||
|
private boolean restructure;
|
||||||
|
private Set<String> processed = new HashSet<>();
|
||||||
|
|
||||||
|
public CodeSystemNavigator(CodeSystem cs) {
|
||||||
|
this.cs = cs;
|
||||||
|
restructure = hasExtraRelationships(cs.getConcept());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRestructure() {
|
||||||
|
return restructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasExtraRelationships(List<ConceptDefinitionComponent> concept) {
|
||||||
|
for (ConceptDefinitionComponent cd : concept) {
|
||||||
|
if (getSubsumedBy(cd) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (ConceptDefinitionComponent cdc : cd.getConcept()) {
|
||||||
|
if (hasExtraRelationships(cdc.getConcept())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ConceptDefinitionComponent> getConcepts(ConceptDefinitionComponent context) {
|
||||||
|
if (context == null) {
|
||||||
|
if (restructure) {
|
||||||
|
List<ConceptDefinitionComponent> res = new ArrayList<>();
|
||||||
|
for (ConceptDefinitionComponent cd : cs.getConcept()) {
|
||||||
|
if (getSubsumedBy(cd) == null) {
|
||||||
|
res.add(cd);
|
||||||
|
processed.add(cd.getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return cs.getConcept();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (restructure) {
|
||||||
|
List<ConceptDefinitionComponent> res = new ArrayList<>();
|
||||||
|
for (ConceptDefinitionComponent cd : context.getConcept()) {
|
||||||
|
res.add(cd);
|
||||||
|
processed.add(cd.getCode());
|
||||||
|
}
|
||||||
|
for (ConceptDefinitionComponent cd : cs.getConcept()) {
|
||||||
|
if (context.getCode().equals(getSubsumedBy(cd)) && !processed.contains(cd.getCode())) {
|
||||||
|
res.add(cd);
|
||||||
|
processed.add(cd.getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return context.getConcept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSubsumedBy(ConceptDefinitionComponent cd) {
|
||||||
|
for (ConceptPropertyComponent cp : cd.getProperty()) {
|
||||||
|
if (cp.getCode().equals("subsumedBy")) {
|
||||||
|
return cp.getValue().primitiveValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ConceptDefinitionComponent> getOtherChildren(ConceptDefinitionComponent context) {
|
||||||
|
List<ConceptDefinitionComponent> res = new ArrayList<>();
|
||||||
|
for (ConceptDefinitionComponent cd : cs.getConcept()) {
|
||||||
|
if (context.getCode().equals(getSubsumedBy(cd)) && processed.contains(cd.getCode())) {
|
||||||
|
res.add(cd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isNotSelectable(CodeSystem cs, ConceptDefinitionComponent def) {
|
public static boolean isNotSelectable(CodeSystem cs, ConceptDefinitionComponent def) {
|
||||||
for (ConceptPropertyComponent p : def.getProperty()) {
|
for (ConceptPropertyComponent p : def.getProperty()) {
|
||||||
if (p.getCode().equals("notSelectable") && p.hasValue() && p.getValue() instanceof BooleanType)
|
if (p.getCode().equals("notSelectable") && p.hasValue() && p.getValue() instanceof BooleanType)
|
||||||
|
|
|
@ -177,6 +177,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||||
|
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||||
|
@ -317,6 +318,9 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean generate(DomainResource r) throws EOperationOutcome, FHIRException, IOException {
|
||||||
|
return generate(null, r, new HashSet<>());
|
||||||
|
}
|
||||||
public boolean generate(DomainResource r, Set<String> outputTracker) throws EOperationOutcome, FHIRException, IOException {
|
public boolean generate(DomainResource r, Set<String> outputTracker) throws EOperationOutcome, FHIRException, IOException {
|
||||||
return generate(null, r, outputTracker);
|
return generate(null, r, outputTracker);
|
||||||
}
|
}
|
||||||
|
@ -2667,7 +2671,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
if (header) {
|
if (header) {
|
||||||
XhtmlNode h = x.h2();
|
XhtmlNode h = x.h2();
|
||||||
h.addText(cs.hasTitle() ? cs.getTitle() : cs.getName());
|
h.addText(cs.hasTitle() ? cs.getTitle() : cs.getName());
|
||||||
addMarkdown(x, cs.getDescription());
|
// .... addMarkdown(x, cs.getDescription());
|
||||||
if (cs.hasCopyright())
|
if (cs.hasCopyright())
|
||||||
generateCopyright(x, cs, lang);
|
generateCopyright(x, cs, lang);
|
||||||
}
|
}
|
||||||
|
@ -2768,9 +2772,10 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
version = version || conceptsHaveVersion(c);
|
version = version || conceptsHaveVersion(c);
|
||||||
hierarchy = hierarchy || c.hasConcept();
|
hierarchy = hierarchy || c.hasConcept();
|
||||||
}
|
}
|
||||||
|
CodeSystemNavigator csNav = new CodeSystemNavigator(cs);
|
||||||
addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, true, commentS, version, deprecated, lang, properties), maps);
|
addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, true, commentS, version, deprecated, lang, properties), maps);
|
||||||
for (ConceptDefinitionComponent c : cs.getConcept()) {
|
for (ConceptDefinitionComponent c : csNav.getConcepts(null)) {
|
||||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, commentS, version, deprecated, maps, cs.getUrl(), cs, lang, properties) || hasExtensions;
|
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy || csNav.isRestructure(), display, commentS, version, deprecated, maps, cs.getUrl(), cs, lang, properties, csNav) || hasExtensions;
|
||||||
}
|
}
|
||||||
// if (langs.size() > 0) {
|
// if (langs.size() > 0) {
|
||||||
// Collections.sort(langs);
|
// Collections.sort(langs);
|
||||||
|
@ -2799,10 +2804,19 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
|
|
||||||
private boolean showPropertyInTable(PropertyComponent cp) {
|
private boolean showPropertyInTable(PropertyComponent cp) {
|
||||||
if (cp.hasCode()) {
|
if (cp.hasCode()) {
|
||||||
|
if (cp.hasExtension(ToolingExtensions.EXT_RENDERED_VALUE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String uri = cp.getUri();
|
||||||
|
if (Utilities.noString(uri)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (uri.contains("#")) {
|
||||||
|
uri = uri.substring(0, uri.indexOf("#"));
|
||||||
|
}
|
||||||
return
|
return
|
||||||
Utilities.existsInList(cp.getUri(), "http://hl7.org/fhir/concept-properties") ||
|
Utilities.existsInList(uri, "http://hl7.org/fhir/concept-properties") ||
|
||||||
codeSystemPropList.contains(cp.getUri()) ||
|
codeSystemPropList.contains(uri);
|
||||||
cp.hasExtension(ToolingExtensions.EXT_RENDERED_VALUE);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3449,7 +3463,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
return "??Lang";
|
return "??Lang";
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int i, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, String lang, List<PropertyComponent> properties) throws FHIRFormatError, DefinitionException, IOException {
|
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int i, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, String lang, List<PropertyComponent> properties, CodeSystemNavigator csNav) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
boolean hasExtensions = false;
|
boolean hasExtensions = false;
|
||||||
XhtmlNode tr = t.tr();
|
XhtmlNode tr = t.tr();
|
||||||
XhtmlNode td = tr.td();
|
XhtmlNode td = tr.td();
|
||||||
|
@ -3618,16 +3632,16 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
td.i().tx("("+mapping.comp.getComment()+")");
|
td.i().tx("("+mapping.comp.getComment()+")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String e : CodeSystemUtilities.getOtherChildren(cs, c)) {
|
for (ConceptDefinitionComponent cc : csNav.getOtherChildren(c)) {
|
||||||
tr = t.tr();
|
tr = t.tr();
|
||||||
td = tr.td();
|
td = tr.td();
|
||||||
String s = Utilities.padLeft("", '.', i*2);
|
String s = Utilities.padLeft("", '.', i*2);
|
||||||
td.addText(s);
|
td.addText(s);
|
||||||
a = td.ah("#"+Utilities.nmtokenize(e));
|
a = td.ah("#"+Utilities.nmtokenize(cc.getCode()));
|
||||||
a.addText(c.getCode());
|
a.addText(c.getCode());
|
||||||
}
|
}
|
||||||
for (ConceptDefinitionComponent cc : c.getConcept()) {
|
for (ConceptDefinitionComponent cc : csNav.getConcepts(c)) {
|
||||||
hasExtensions = addDefineRowToTable(t, cc, i+1, hasHierarchy, hasDisplay, comment, version, deprecated, maps, system, cs, lang, properties) || hasExtensions;
|
hasExtensions = addDefineRowToTable(t, cc, i+1, hasHierarchy, hasDisplay, comment, version, deprecated, maps, system, cs, lang, properties, csNav) || hasExtensions;
|
||||||
}
|
}
|
||||||
return hasExtensions;
|
return hasExtensions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
GraphQLEngineTests.class,
|
GraphQLEngineTests.class,
|
||||||
LiquidEngineTests.class,
|
LiquidEngineTests.class,
|
||||||
FHIRPathTests.class,
|
FHIRPathTests.class,
|
||||||
|
NarrativeGenerationTests.class,
|
||||||
NarrativeGeneratorTests.class,
|
NarrativeGeneratorTests.class,
|
||||||
ShexGeneratorTests.class,
|
ShexGeneratorTests.class,
|
||||||
BaseDateTimeTypeTest.class,
|
BaseDateTimeTypeTest.class,
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
|
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
|
import org.hl7.fhir.r5.model.DomainResource;
|
||||||
|
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||||
|
import org.hl7.fhir.r5.model.ExpressionNode.CollectionStatus;
|
||||||
|
import org.hl7.fhir.r5.model.MetadataResource;
|
||||||
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||||
|
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.AssertionResponseTypes;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.SetupActionAssertComponent;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.SetupActionOperationComponent;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.TestActionComponent;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.TestScriptFixtureComponent;
|
||||||
|
import org.hl7.fhir.r5.model.TestScript.TestScriptTestComponent;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.utils.CodingUtilities;
|
||||||
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||||
|
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.cache.PackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||||
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
public class NarrativeGenerationTests {
|
||||||
|
|
||||||
|
public static class TestDetails {
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
public TestDetails(Element test) {
|
||||||
|
super();
|
||||||
|
id = test.getAttribute("id");
|
||||||
|
}
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FHIRPathEngine fp;
|
||||||
|
|
||||||
|
@Parameters(name = "{index}: file {0}")
|
||||||
|
public static Iterable<Object[]> data() throws ParserConfigurationException, IOException, FHIRFormatError, SAXException {
|
||||||
|
|
||||||
|
Document tests = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r5", "narrative", "manifest.xml"));
|
||||||
|
Element test = XMLUtil.getFirstChild(tests.getDocumentElement());
|
||||||
|
List<Object[]> objects = new ArrayList<Object[]>();
|
||||||
|
while (test != null && test.getNodeName().equals("test")) {
|
||||||
|
TestDetails t = new TestDetails(test);
|
||||||
|
objects.add(new Object[] {t.getId(), t});
|
||||||
|
test = XMLUtil.getNextSibling(test);
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final TestDetails test;
|
||||||
|
private IWorkerContext context;
|
||||||
|
private List<ValidationMessage> messages;
|
||||||
|
|
||||||
|
public NarrativeGenerationTests(String id, TestDetails test) {
|
||||||
|
this.test = test;
|
||||||
|
this.context = TestingUtilities.context();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
NarrativeGenerator gen = new NarrativeGenerator("", "http://hl7.org/fhir", context);
|
||||||
|
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId()+"-expected.xml"), new FileOutputStream(TestingUtilities.tempFile("narrative", test.getId()+"-expected.xml")));
|
||||||
|
DomainResource source = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId()+"-input.xml"));
|
||||||
|
DomainResource target = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId()+"-expected.xml"));
|
||||||
|
gen.generate(source);
|
||||||
|
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(TestingUtilities.tempFile("narrative", test.getId()+"-actual.xml")), source);
|
||||||
|
Assert.assertTrue("Output does not match expected", source.equalsDeep(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2
pom.xml
2
pom.xml
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<hapi_fhir_version>4.1.0</hapi_fhir_version>
|
<hapi_fhir_version>4.1.0</hapi_fhir_version>
|
||||||
<validator_test_case_version>1.0.14-SNAPSHOT</validator_test_case_version>
|
<validator_test_case_version>1.0.15-SNAPSHOT</validator_test_case_version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<artifactId>org.hl7.fhir.core</artifactId>
|
<artifactId>org.hl7.fhir.core</artifactId>
|
||||||
|
|
Loading…
Reference in New Issue