package org.gedcomx.util; import junit.framework.TestCase; import org.gedcomx.Gedcomx; import org.gedcomx.common.URI; import org.gedcomx.conclusion.PlaceDescription; import org.gedcomx.conclusion.Relationship; import org.gedcomx.records.FieldValue; import org.gedcomx.source.SourceReference; import javax.xml.bind.JAXBException; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Class for testing DocCheck * User: Randy Wilson * Date: 10/6/2014 * Time: 9:51 PM */ public class TestDocCheck extends TestCase { /** * Test the DocCheck on a record (but without fields here). * @throws JAXBException */ public void testDocCheck() throws JAXBException { Gedcomx doc = MarshalUtil.unmarshal(getClass().getClassLoader().getResourceAsStream("gedcomx-record.xml")); URI wrongLocalUri = new URI("#wrongId"); SourceReference wrongSourceReference = new SourceReference(); wrongSourceReference.setDescriptionRef(wrongLocalUri); // No problems with original record checkDoc(doc); // Break description ref URI descriptionRef = doc.getDescriptionRef(); doc.setDescriptionRef(null); checkDoc(doc, 1); doc.setDescriptionRef(wrongLocalUri); checkDoc(doc, 1); doc.setDescriptionRef(descriptionRef); // repair broken ref. // Break componentOf DocMap docMap = new DocMap(doc); SourceReference componentOf = docMap.getMainSourceDescription().getComponentOf(); docMap.getMainSourceDescription().setComponentOf(wrongSourceReference); checkDoc(doc, 2); docMap.getMainSourceDescription().setComponentOf(componentOf); // repair // Break source SourceReference sourceReference = docMap.getMainSourceDescription().getSources().get(0); descriptionRef = sourceReference.getDescriptionRef(); sourceReference.setDescriptionRef(wrongLocalUri); checkDoc(doc, 3); sourceReference.setDescriptionRef(descriptionRef); PlaceDescription place = doc.getPlaces().get(0); String temp = place.getId(); place.setId(null); checkDoc(doc, 13); place.setId(temp); // Break relationship Relationship rel = doc.getRelationships().get(0); URI person1ref = rel.getPerson1().getResource(); // Error 4: resourceId but no resource URI rel.getPerson1().setResource(null); rel.getPerson1().setResourceId(person1ref.toString()); checkDoc(doc, 4); // Error 5: local resourceId that couldn't be found. rel.getPerson1().setResource(wrongLocalUri); rel.getPerson1().setResourceId(null); checkDoc(doc, 5); // Error 6: full URI to person that is found in the doc. Should use local #id. rel.getPerson1().setResource(docMap.getPerson(person1ref).getPersistentId()); checkDoc(doc, 6); // Error 7: both URIs to persons outside the document. URI person2ref = rel.getPerson2().getResource(); rel.getPerson1().setResource(new URI("https://external.com/123")); rel.getPerson2().setResource(new URI("https://external.com/456")); checkDoc(doc, 7); rel.getPerson1().setResource(person1ref); // repair rel.getPerson2().setResource(person2ref); // repair // Errors 8, 9, 10, 11, 12: Bad source references on relationship.sources, relationship.media, person.sources, person.media, gender rel.addSource(wrongSourceReference); rel.addMedia(wrongSourceReference); doc.getPersons().get(0).addSource(wrongSourceReference); doc.getPersons().get(0).addMedia(wrongSourceReference); doc.getPersons().get(1).getGender().addSource(wrongSourceReference); checkDoc(doc, 8, 9, 10, 11, 12); // Done, so don't bother repairing the above. } public void testDocCheckWithFields() throws JAXBException { Gedcomx record = MarshalUtil.unmarshal(getClass().getClassLoader().getResourceAsStream("gedcomx-record.xml")); Gedcomx collection = MarshalUtil.unmarshal(getClass().getClassLoader().getResourceAsStream("gedcomx-collection.xml")); // Known missing label IDs checkFields(record, collection, "IMAGE_ID_NORM", "IMAGE_ARK"); // Change a field ID, and make sure it isn't found. FieldValue fieldValue = record.getPersons().get(0).getFacts().get(0).getDate().getFields().get(0).getValues().get(0); String labelId = fieldValue.getLabelId(); fieldValue.setLabelId(labelId + "_BROKEN"); checkFields(record, collection, "IMAGE_ID_NORM", "IMAGE_ARK", labelId + "_BROKEN"); } private static final Pattern errorMessagePattern = Pattern.compile(".*(?:Error|Warning) ([0-9]+):.*"); private void checkDoc(Gedcomx doc, Integer... errorCodes) { String errors = DocCheck.checkDocument(doc); if (errors == null) { assertEquals(errorCodes.length, 0); } else { Set<Integer> actualErrorCodes = new HashSet<Integer>(); for (String line : errors.split("\n")) { Matcher m = errorMessagePattern.matcher(line); if (m.matches()) { actualErrorCodes.add(Integer.parseInt(m.group(1))); } } assertEquals(errorCodes.length, actualErrorCodes.size()); for (Integer errorCode : errorCodes) { assertTrue("Did not find error code: " + errorCode, actualErrorCodes.contains(errorCode)); } } } private static final Pattern missingLabelIdPattern = Pattern.compile("Error 13:.* labelId '([^']*)' had no .*"); private void checkFields(Gedcomx record, Gedcomx collection, String... missingLabelIds) { String errors = DocCheck.checkDocument(record, collection); if (errors == null) { assertEquals(missingLabelIds.length, 0); } else { Set<String> actualMissingLabelIds = new HashSet<String>(); for (String line : errors.split("\n")) { Matcher m = missingLabelIdPattern.matcher(line); if (m.matches()) { actualMissingLabelIds.add(m.group(1)); } } assertEquals(missingLabelIds.length, actualMissingLabelIds.size()); for (String labelId : missingLabelIds) { assertTrue("Did not error for labelId '" + labelId + "'", actualMissingLabelIds.contains(labelId)); } } } }