package nl.knaw.huygens.alexandria.api.model.text.view; /* * #%L * alexandria-api * ======= * Copyright (C) 2015 - 2017 Huygens ING (KNAW) * ======= * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import nl.knaw.huygens.alexandria.api.model.text.view.ElementView.AttributeFunction; import nl.knaw.huygens.alexandria.api.model.text.view.ElementView.AttributeMode; import nl.knaw.huygens.alexandria.test.AlexandriaTest; public class TextViewDefinitionTest extends AlexandriaTest { private static ObjectMapper om = new ObjectMapper(); @BeforeClass public static void beforeClass() { om.registerModule(new Jdk8Module()); } @Test public void testJsonSerializing() throws IOException { TextViewDefinition d = new TextViewDefinition(); d.setDescription("Test definition"); d.getElementViewDefinitions().put(TextViewDefinition.DEFAULT_ATTRIBUTENAME, new ElementViewDefinition().setElementMode(ElementView.ElementMode.show).setAttributeMode("showAll")); d.getElementViewDefinitions().put("note", new ElementViewDefinition().setElementMode(ElementView.ElementMode.hide)); d.getElementViewDefinitions().put("persName", new ElementViewDefinition().setElementMode(ElementView.ElementMode.show).setWhen("attribute(resp).is(\"#ed\")")); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(d); assertThat(tvdp.isValid()).isTrue(); String json = om.writeValueAsString(d); String expected = singleQuotesToDouble("{'textView':"// + "{"// + "'description':'Test definition',"// + "'annotationLayers':{}," + "'annotationLayerDepthOrder':[]," + "'elements':{"// + "':default':{'elementMode':'show','attributeMode':'showAll'},"// + "'note':{'elementMode':'hide'},"// + "'persName':{'elementMode':'show','when':'attribute(resp).is(\\'#ed\\')'}"// + "}"// + "}}"); TextViewDefinition d2 = om.readValue(json, TextViewDefinition.class); assertThat(json).isEqualTo(expected); assertThat(d2).isEqualToComparingFieldByFieldRecursively(d); } // http://www.w3schools.com/xml/xml_elements.asp : // XML elements must follow these naming rules: // // Element names are case-sensitive // Element names must start with a letter or underscore // Element names cannot start with the letters xml (or XML, or Xml, etc) // Element names can contain letters, digits, hyphens, underscores, and periods // Element names cannot contain spaces @Test public void testValidationOfInvalidElementNamesFails() throws IOException { TextViewDefinition d = new TextViewDefinition(); d.getElementViewDefinitions().put("3lement", new ElementViewDefinition().setElementMode(ElementView.ElementMode.show)); d.getElementViewDefinitions().put("xmlIsDaBomb", new ElementViewDefinition().setElementMode(ElementView.ElementMode.show)); d.getElementViewDefinitions().put("element?", new ElementViewDefinition().setElementMode(ElementView.ElementMode.show)); d.getElementViewDefinitions().put("e le ment", new ElementViewDefinition().setElementMode(ElementView.ElementMode.show)); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(d); assertThat(tvdp.isValid()).isFalse(); assertThat(tvdp.getErrors()).containsExactly(// "\"3lement\" is not a valid element name: element names must start with a letter or underscore.", // "\"xmlIsDaBomb\" is not a valid element name: element names cannot start with the letters xml (or XML, or Xml, etc).", // "\"element?\" is not a valid element name: element names can only contain letters, digits, hyphens, underscores, and periods.", // "\"e le ment\" is not a valid element name: element names cannot contain spaces."// ); } @Test public void testParsingOfInvalidAttributeModeFails() throws IOException { TextViewDefinition d = new TextViewDefinition(); ElementViewDefinition evd1 = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("showNone"); d.getElementViewDefinitions().put("element", evd1); ElementViewDefinition evd2 = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("showOnly"); d.getElementViewDefinitions().put("element2", evd2); ElementViewDefinition evd3 = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("hideOnly"); d.getElementViewDefinitions().put("element3", evd3); ElementViewDefinition evd4 = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("hideAll"); d.getElementViewDefinitions().put("element4", evd4); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(d); assertThat(tvdp.isValid()).isFalse(); assertThat(tvdp.getErrors()).containsExactly(// "element: \"showNone\" is not a valid attributeMode. Valid attributeMode values are: \"showAll\", \"showOnly attribute...\", \"hideAll\", \"hideOnly attribute...\".", // "element2: \"showOnly\" needs one or more attribute names.", // "element3: \"hideOnly\" needs one or more attribute names."// ); } @Test public void testParsingOfDefinitionWithJustAttributeModePasses() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setAttributeMode("showOnly xml:id ref"); tvd.getElementViewDefinitions().put("p", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("p"); ElementView elementView = elementViewMap.get("p"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(ElementView.AttributeMode.showOnly); assertThat(elementView.getRelevantAttributes()).containsExactly("xml:id", "ref"); testJsonSerialization(textView); } @Test public void testParsingOfShowOnlyAttributeModeParameters() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("showOnly xml:id ref"); tvd.getElementViewDefinitions().put("p", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("p"); ElementView elementView = elementViewMap.get("p"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(ElementView.AttributeMode.showOnly); assertThat(elementView.getRelevantAttributes()).containsExactly("xml:id", "ref"); testJsonSerialization(textView); } @Test public void testParsingOfHideOnlyAttributeModeParameters() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setAttributeMode("hideOnly note"); tvd.getElementViewDefinitions().put("element", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("element"); ElementView elementView = elementViewMap.get("element"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(ElementView.AttributeMode.hideOnly); assertThat(elementView.getRelevantAttributes()).containsExactly("note"); testJsonSerialization(textView); } @Test public void testParsingOfIsWhen() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setWhen("attribute({resp}).is('#ed1')"); tvd.getElementViewDefinitions().put("element", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("element"); ElementView elementView = elementViewMap.get("element"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(AttributeMode.showAll); // default assertThat(elementView.getRelevantAttributes()).isEmpty(); AttributePreCondition preCondition = elementView.getPreCondition().get(); assertThat(preCondition.getAttribute()).isEqualTo("{resp}"); assertThat(preCondition.getFunction()).isEqualTo(AttributeFunction.is); assertThat(preCondition.getValues()).containsExactly("#ed1"); testJsonSerialization(textView); } @Test public void testParsingOfIsNotWhen() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setWhen("attribute(resp).isNot('#ed2')"); tvd.getElementViewDefinitions().put("element", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("element"); ElementView elementView = elementViewMap.get("element"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(AttributeMode.showAll); // default assertThat(elementView.getRelevantAttributes()).isEmpty(); AttributePreCondition preCondition = elementView.getPreCondition().get(); assertThat(preCondition.getAttribute()).isEqualTo("resp"); assertThat(preCondition.getFunction()).isEqualTo(AttributeFunction.isNot); assertThat(preCondition.getValues()).containsExactly("#ed2"); testJsonSerialization(textView); } @Test public void testParsingOfFirstOfWhen() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setWhen("attribute(resp).firstOf('#ed1','#ed2','')"); tvd.getElementViewDefinitions().put("element", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); TextView textView = tvdp.getTextView().get(); Map<String, ElementView> elementViewMap = textView.getElementViewMap(); assertThat(tvdp.isValid()).isTrue(); assertThat(elementViewMap).containsKey("element"); ElementView elementView = elementViewMap.get("element"); assertThat(elementView.getElementMode()).isNotNull(); assertThat(elementView.getElementMode()).isEqualTo(ElementView.ElementMode.show); assertThat(elementView.getAttributeMode()).isEqualTo(AttributeMode.showAll); // default assertThat(elementView.getRelevantAttributes()).isEmpty(); AttributePreCondition preCondition = elementView.getPreCondition().get(); assertThat(preCondition.getAttribute()).isEqualTo("resp"); assertThat(preCondition.getFunction()).isEqualTo(AttributeFunction.firstOf); assertThat(preCondition.getValues()).containsExactly("#ed1", "#ed2", ""); testJsonSerialization(textView); } private void testJsonSerialization(TextView textView) throws JsonProcessingException, IOException, JsonParseException, JsonMappingException { String json = om.writeValueAsString(textView); TextView tv2 = om.readValue(json, TextView.class); assertThat(tv2).isEqualToComparingFieldByFieldRecursively(textView); } @Test public void testParsingOfInvalidWhen() throws IOException { TextViewDefinition tvd = new TextViewDefinition(); ElementViewDefinition evd = new ElementViewDefinition()// .setElementMode(ElementView.ElementMode.show)// .setWhen("attribute(resp).myownfunction('#ed1','#ed2','')"); tvd.getElementViewDefinitions().put("element", evd); TextViewDefinitionParser tvdp = new TextViewDefinitionParser(tvd); assertThat(tvdp.isValid()).isFalse(); assertThat(tvdp.getErrors()).containsExactly( "element: \"attribute(resp).myownfunction('#ed1','#ed2','')\" is not a valid condition. Valid 'when' values are: \"attribute(a).is('value')\", \"attribute(a).isNot('value')\", \"attribute(a).firstOf('value0','value1',...)\"."); } }