package ca.uhn.fhir.util; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseReference; import org.junit.AfterClass; import org.junit.Test; import org.mockito.ArgumentCaptor; import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.dstu2.composite.IdentifierDt; import ca.uhn.fhir.model.dstu2.composite.MoneyDt; import ca.uhn.fhir.model.dstu2.composite.QuantityDt; import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.dstu2.resource.Organization; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.primitive.MarkdownDt; import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.parser.DataFormatException; public class FhirTerserDstu2Test { private static FhirContext ourCtx = FhirContext.forDstu2(); @Test public void testCloneIntoComposite() { QuantityDt source = new QuantityDt(); source.setCode("CODE"); MoneyDt target = new MoneyDt(); ourCtx.newTerser().cloneInto(source, target, true); assertEquals("CODE", target.getCode()); } @Test public void testCloneIntoCompositeMismatchedFields() { QuantityDt source = new QuantityDt(); source.setSystem("SYSTEM"); source.setUnit("UNIT"); IdentifierDt target = new IdentifierDt(); ourCtx.newTerser().cloneInto(source, target, true); assertEquals("SYSTEM", target.getSystem()); try { ourCtx.newTerser().cloneInto(source, target, false); fail(); } catch (DataFormatException e) { // good } } /** * See #369 */ @Test public void testCloneIntoExtension() { Patient patient = new Patient(); patient.addUndeclaredExtension(new ExtensionDt(false, "http://example.com", new StringDt("FOO"))); Patient target = new Patient(); ourCtx.newTerser().cloneInto(patient, target, false); List<ExtensionDt> exts = target.getUndeclaredExtensionsByUrl("http://example.com"); assertEquals(1, exts.size()); assertEquals("FOO", ((StringDt)exts.get(0).getValue()).getValue()); } @Test public void testCloneIntoPrimitive() { StringDt source = new StringDt("STR"); MarkdownDt target = new MarkdownDt(); ourCtx.newTerser().cloneInto(source, target, true); assertEquals("STR", target.getValueAsString()); } @Test public void testCloneIntoPrimitiveFails() { StringDt source = new StringDt("STR"); MoneyDt target = new MoneyDt(); ourCtx.newTerser().cloneInto(source, target, true); assertTrue(target.isEmpty()); try { ourCtx.newTerser().cloneInto(source, target, false); fail(); } catch (DataFormatException e) { // good } } /** * See #369 */ @Test public void testCloneIntoValues() { Observation obs = new Observation(); obs.setValue(new StringDt("AAA")); obs.setComments("COMMENTS"); Observation target = new Observation(); ourCtx.newTerser().cloneInto(obs, target, false); assertEquals("AAA", ((StringDt)obs.getValue()).getValue()); assertEquals("COMMENTS", obs.getComments()); } @Test public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() { Patient p = new Patient(); p.addName().addFamily("PATIENT"); Organization o = new Organization(); o.getNameElement().setValue("ORGANIZATION"); p.getContained().getContainedResources().add(o); FhirTerser t = ourCtx.newTerser(); List<StringDt> strings = t.getAllPopulatedChildElementsOfType(p, StringDt.class); assertEquals(2, strings.size()); assertThat(strings, containsInAnyOrder(new StringDt("PATIENT"), new StringDt("ORGANIZATION"))); } @Test public void testGetAllPopulatedChildElementsOfTypeDoesntDescendIntoEmbedded() { Patient p = new Patient(); p.addName().addFamily("PATIENT"); Bundle b = new Bundle(); b.addEntry().setResource(p); b.addLink().setRelation("BUNDLE"); FhirTerser t = ourCtx.newTerser(); List<StringDt> strings = t.getAllPopulatedChildElementsOfType(b, StringDt.class); assertEquals(1, strings.size()); assertThat(strings, containsInAnyOrder(new StringDt("BUNDLE"))); } @Test public void testGetResourceReferenceInExtension() { Patient p = new Patient(); p.addName().addFamily("PATIENT"); Organization o = new Organization(); o.setName("ORG"); ResourceReferenceDt ref = new ResourceReferenceDt(o); ExtensionDt ext = new ExtensionDt(false, "urn:foo", ref); p.addUndeclaredExtension(ext); List<IBaseReference> refs = ourCtx.newTerser().getAllPopulatedChildElementsOfType(p, IBaseReference.class); assertEquals(1, refs.size()); assertSame(ref, refs.get(0)); } @Test public void testVisitWithModelVisitor2() { IModelVisitor2 visitor = mock(IModelVisitor2.class); ArgumentCaptor<IBase> element = ArgumentCaptor.forClass(IBase.class); ArgumentCaptor<List<IBase>> containingElementPath = ArgumentCaptor.forClass(getListClass(IBase.class)); ArgumentCaptor<List<BaseRuntimeChildDefinition>> childDefinitionPath = ArgumentCaptor.forClass(getListClass(BaseRuntimeChildDefinition.class)); ArgumentCaptor<List<BaseRuntimeElementDefinition<?>>> elementDefinitionPath = ArgumentCaptor.forClass(getListClass2()); when(visitor.acceptElement(element.capture(), containingElementPath.capture(), childDefinitionPath.capture(), elementDefinitionPath.capture())).thenReturn(true); Patient p = new Patient(); p.addLink().getTypeElement().setValue("CODE"); ourCtx.newTerser().visit(p, visitor); assertEquals(3, element.getAllValues().size()); assertSame(p, element.getAllValues().get(0)); assertSame(p.getLinkFirstRep(), element.getAllValues().get(1)); assertSame(p.getLinkFirstRep().getTypeElement(), element.getAllValues().get(2)); assertEquals(3, containingElementPath.getAllValues().size()); // assertEquals(0, containingElementPath.getAllValues().get(0).size()); // assertEquals(1, containingElementPath.getAllValues().get(1).size()); // assertEquals(2, containingElementPath.getAllValues().get(2).size()); } @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); } /** * See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type */ private static <T> Class<List<T>> getListClass(Class<T> theClass) { return new ClassGetter<List<T>>() { }.get(); } /** * See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type */ private static Class<List<BaseRuntimeElementDefinition<?>>> getListClass2() { return new ClassGetter<List<BaseRuntimeElementDefinition<?>>>() { }.get(); } /** * See http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type */ private static abstract class ClassGetter<T> { @SuppressWarnings("unchecked") public final Class<T> get() { final ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); Type type = superclass.getActualTypeArguments()[0]; if (type instanceof ParameterizedType) { return (Class<T>) ((ParameterizedType) type).getOwnerType(); } return (Class<T>) type; } } }