package org.molgenis.data.support; import com.google.gson.JsonSyntaxException; import org.molgenis.data.Entity; import org.molgenis.data.EntityReferenceCreator; import org.molgenis.data.meta.model.*; import org.molgenis.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static com.google.common.collect.Lists.newArrayList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.molgenis.data.meta.AttributeType.*; import static org.molgenis.data.meta.model.EntityType.AttributeRole.ROLE_ID; import static org.testng.Assert.*; @ContextConfiguration(classes = { MapOfStringsExpressionEvaluatorTest.Config.class }) public class MapOfStringsExpressionEvaluatorTest extends AbstractTestNGSpringContextTests { private Entity entity; private EntityType emd; private EntityType refEmd; @Autowired private EntityTypeFactory entityTypeFactory; @Autowired private AttributeFactory attributeFactory; private EntityType createDynamicLocationMetaData() { return entityTypeFactory.create().setSimpleName("Location") .addAttribute(attributeFactory.create().setName("Identifier").setDataType(STRING), ROLE_ID) .addAttribute(attributeFactory.create().setName("Chromosome").setDataType(STRING)) .addAttribute(attributeFactory.create().setName("Position").setDataType(STRING)); } private EntityType createDynamicSourceMetaData() { return entityTypeFactory.create().setSimpleName("Source") .addAttribute(attributeFactory.create().setName("Identifier").setDataType(STRING), ROLE_ID) .addAttribute(attributeFactory.create().setName("Int").setDataType(INT)) .addAttribute(attributeFactory.create().setName("String").setDataType(STRING)) .addAttribute(attributeFactory.create().setName("NonNumericString").setDataType(STRING)) .addAttribute(attributeFactory.create().setName("Long").setDataType(LONG)); } @BeforeMethod public void createEntity() { emd = createDynamicSourceMetaData(); refEmd = createDynamicLocationMetaData(); entity = new DynamicEntity(emd); entity.set("Int", 1); entity.set("String", "12"); entity.set("Long", 10L); entity.set("NonNumericString", "Hello World!"); } @Test public void testMapOfStringsEvaluatorConstructorChecksIfAttributeHasExpression() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("#CHROM").getMock(); when(amd.getDataType()).thenReturn(STRING); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected NPE"); } catch (NullPointerException expected) { assertEquals(expected.getMessage(), "Attribute has no expression."); } } @Test public void testMapOfStringsEvaluatorConstructorChecksIfAttributeHasRefEntity() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("location").getMock(); when(amd.getDataType()).thenReturn(XREF); when(amd.getExpression()).thenReturn("{'a':b}"); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected IllegalArgumentException."); } catch (NullPointerException expected) { assertEquals(expected.getMessage(), "refEntity not specified."); } } @Test public void testMapOfStringsEvaluatorConstructorChecksIfExpressionIsMap() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("location").getMock(); when(amd.getDataType()).thenReturn(XREF); when(amd.getRefEntity()).thenReturn(refEmd); when(amd.getExpression()).thenReturn("hallo"); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected JSON exception"); } catch (JsonSyntaxException expected) { } } @Test public void testMapOfStringsEvaluatorConstructorChecksThatExpressionIsMapOfStrings() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("#CHROM").getMock(); when(amd.getDataType()).thenReturn(XREF); when(amd.getRefEntity()).thenReturn(refEmd); when(amd.getExpression()).thenReturn("{'Chromosome':{'hallo1':'bla'}}"); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { assertEquals(expected.getMessage(), "Nested expressions not supported, expression must be Map<String,String>."); } } @Test public void testMapOfStringsEvaluatorConstructorChecksIfCalculatedAttributesAllExist() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("#CHROM").getMock(); when(amd.getDataType()).thenReturn(STRING); when(amd.getRefEntity()).thenReturn(refEmd); when(amd.getExpression()).thenReturn("{'hallo':String}"); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected illegal argument exception"); } catch (IllegalArgumentException expected) { assertEquals(expected.getMessage(), "Unknown target attribute: hallo."); } } @Test public void testMapOfStringsEvaluatorConstructorChecksIfMentionedAttributesAllExist() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("#CHROM").getMock(); when(amd.getDataType()).thenReturn(STRING); when(amd.getRefEntity()).thenReturn(refEmd); when(amd.getExpression()).thenReturn("{'Chromosome':hallo}"); try { new MapOfStringsExpressionEvaluator(amd, emd); fail("Expected illegal argument exception"); } catch (IllegalArgumentException expected) { assertEquals(expected.getMessage(), "Expression for attribute 'Chromosome' references non-existant attribute 'hallo'."); } } @Test public void testEvaluate() { Attribute amd = when(mock(Attribute.class).getName()).thenReturn("#CHROM").getMock(); when(amd.getDataType()).thenReturn(XREF); when(amd.getRefEntity()).thenReturn(refEmd); when(amd.getExpression()).thenReturn("{'Chromosome':String, 'Position':Int}"); when(amd.getEntityType()).thenReturn(mock(EntityType.class)); when(amd.getDataType()).thenReturn(XREF); ExpressionEvaluator evaluator = new MapOfStringsExpressionEvaluator(amd, emd); Entity expected = new DynamicEntity(refEmd); expected.set("Chromosome", "12"); expected.set("Position", "1"); Entity actual = (Entity) evaluator.evaluate(entity); assertTrue(EntityUtils.equals(actual, expected)); } @Autowired ApplicationContext applicationContext; @BeforeClass public void bootstrap() { // bootstrap meta data EntityTypeMetadata entityTypeMeta = applicationContext.getBean(EntityTypeMetadata.class); entityTypeMeta.setBackendEnumOptions(newArrayList("test")); applicationContext.getBean(AttributeMetadata.class).bootstrap(entityTypeMeta); applicationContext.getBean(EntityTypeMetadata.class).bootstrap(entityTypeMeta); applicationContext.getBean(PackageMetadata.class).bootstrap(entityTypeMeta); applicationContext.getBean(TagMetadata.class).bootstrap(entityTypeMeta); } @Configuration @ComponentScan({ "org.molgenis.data.meta.model", "org.molgenis.data.system.model", "org.molgenis.data.populate" }) public static class Config { @Bean public EntityReferenceCreator entityReferenceCreator() { return mock(EntityReferenceCreator.class); } } }