ref #7443, ref #10432 add formatting and partly parsing for name in-authors
[cdmlib.git] / cdmlib-model / src / test / java / eu / etaxonomy / cdm / strategy / cache / name / TaxonNameDefaultCacheStrategyTest.java
index 0e8ccb7b45cd95186d8e2c92984950e6b51cc891..c6745e1d701c51b1815d879dd5ac05f4dce258d8 100644 (file)
@@ -14,7 +14,8 @@ import static org.junit.Assert.assertNull;
 
 import java.util.List;
 
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -23,10 +24,12 @@ import eu.etaxonomy.cdm.common.UTF8;
 import eu.etaxonomy.cdm.model.agent.Person;
 import eu.etaxonomy.cdm.model.agent.Team;
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
+import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
 import eu.etaxonomy.cdm.model.name.IBotanicalName;
 import eu.etaxonomy.cdm.model.name.INonViralName;
 import eu.etaxonomy.cdm.model.name.IZoologicalName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
 import eu.etaxonomy.cdm.model.name.Rank;
@@ -48,7 +51,7 @@ import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
 public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase {
 
     @SuppressWarnings("unused")
-       private static final Logger logger = Logger.getLogger(TaxonNameDefaultCacheStrategyTest.class);
+    private static final Logger logger = LogManager.getLogger();
 
     private TaxonNameDefaultCacheStrategy strategy;
 
@@ -59,8 +62,10 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
 
     private static final String authorString = "L.";
     private static final String exAuthorString = "Exaut.";
+    private static final String inAuthorString = "Inaut. B.";
     private static final String basAuthorString = "Basio, A.";
     private static final String exBasAuthorString = "ExBas. N.";
+    private static final String inBasAuthorString = "Inbas., C.";
 
     private static final String referenceTitle = "My Reference";
 
@@ -71,8 +76,10 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
     private TaxonName subSpeciesName;
     private TeamOrPersonBase<?> author;
     private TeamOrPersonBase<?> exAuthor;
+    private TeamOrPersonBase<?> inAuthor;
     private TeamOrPersonBase<?> basAuthor;
     private TeamOrPersonBase<?> exBasAuthor;
+    private TeamOrPersonBase<?> inBasAuthor;
     private Reference citationRef;
 
     @Before
@@ -89,16 +96,20 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         subSpeciesName = TaxonNameFactory.PARSED_BOTANICAL(subSpeciesNameString);
 
         author = Person.NewInstance();
-        author.setNomenclaturalTitle(authorString);
+        author.setNomenclaturalTitleCache(authorString, true);
         exAuthor = Person.NewInstance();
-        exAuthor.setNomenclaturalTitle(exAuthorString);
+        exAuthor.setNomenclaturalTitleCache(inAuthorString, true);
+        inAuthor = Person.NewInstance();
+        inAuthor.setNomenclaturalTitleCache(inAuthorString, true);
         basAuthor = Person.NewInstance();
-        basAuthor.setNomenclaturalTitle(basAuthorString);
+        basAuthor.setNomenclaturalTitleCache(basAuthorString, true);
         exBasAuthor = Person.NewInstance();
-        exBasAuthor.setNomenclaturalTitle(exBasAuthorString);
+        exBasAuthor.setNomenclaturalTitleCache(exBasAuthorString, true);
+        inBasAuthor = Person.NewInstance();
+        inBasAuthor.setNomenclaturalTitleCache(inBasAuthorString, true);
 
         citationRef = ReferenceFactory.newGeneric();
-        citationRef.setTitleCache(referenceTitle, true);
+        citationRef.setTitle(referenceTitle);
     }
 
 //**************************** TESTS **************************************************
@@ -113,6 +124,8 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
     public void testGetFullTitleCache() {
         subSpeciesName.setNomenclaturalReference(citationRef);
         Assert.assertEquals(subSpeciesNameString + ", " +  referenceTitle, subSpeciesName.getFullTitleCache());
+        subSpeciesName.setNomenclaturalMicroReference("25");
+        Assert.assertEquals(subSpeciesNameString + ", " +  referenceTitle + ": 25", subSpeciesName.getFullTitleCache());
         //TODO not yet completed
     }
 
@@ -171,6 +184,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         botName.setInfraGenericEpithet("Infragenus");
         Assert.assertEquals("", "Genus sect. Infragenus", botName.getNameCache());
         botName.setRank(Rank.SUBSECTION_BOTANY());
+        botName.setNameCache(null, false);
         Assert.assertEquals("", "Genus subsect. Infragenus", botName.getNameCache());
 
         //zool. specific ranks (we don't have markers here therefore no problem should exist
@@ -195,16 +209,16 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         assertEquals("Name cache should be Lepidocaryum (Infralepi) tenue var. tenue", "Lepidocaryum (Infralepi) tenue var. tenue", botName.getNameCache());
 
         botName.setInfraGenericEpithet(" ");
-        //Note: This test may fail if aspectj doesn't work correctly
+        botName.setNameCache(null, false);
         assertEquals("Empty infrageneric epithet must be neglegted", "Lepidocaryum tenue var. tenue", botName.getNameCache());
     }
 
     @Test
     public void testGetAuthorshipCache() {
         this.speciesName.setCombinationAuthorship(author);
-        assertEquals(author.getNomenclaturalTitle(), speciesName.getAuthorshipCache());
+        assertEquals(author.getNomenclaturalTitleCache(), speciesName.getAuthorshipCache());
         this.speciesName.setBasionymAuthorship(basAuthor);
-        String expected = strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitle()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+author.getNomenclaturalTitle();
+        String expected = strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitleCache()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+author.getNomenclaturalTitleCache();
         assertEquals(expected, speciesName.getAuthorshipCache());
         String authorshipcache = "authorshipcache";
         speciesName.setAuthorshipCache(authorshipcache);
@@ -214,11 +228,12 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         assertEquals(speciesNameString + " " + authorshipcache, speciesName.getFullTitleCache());
         //unprotected
         speciesName.setProtectedAuthorshipCache(false);
-        String atomizedAuthorCache = strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitle()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+exAuthor.getNomenclaturalTitle();
+        String atomizedAuthorCache = strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitleCache()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+exAuthor.getNomenclaturalTitleCache();
         assertEquals(atomizedAuthorCache, speciesName.getAuthorshipCache());
-        String atomizedTitleCache = speciesNameString + " "+ strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitle()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+exAuthor.getNomenclaturalTitle();
+        String atomizedTitleCache = speciesNameString + " "+ strategy.getBasionymStart()+ basAuthor.getNomenclaturalTitleCache()+strategy.getBasionymEnd()+strategy.getBasionymAuthorCombinationAuthorSeperator()+exAuthor.getNomenclaturalTitleCache();
         //Note: This test may fail if aspectj doesn't work correctly
         assertEquals(atomizedTitleCache, speciesName.getTitleCache());
+        speciesName.setFullTitleCache(null, false);
         assertEquals(atomizedTitleCache, speciesName.getFullTitleCache());
     }
 
@@ -226,34 +241,39 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
     public void testHybridNames() {
         //Note \u00D7 : hybrid sign (multiplication sign)
         this.speciesName.setCombinationAuthorship(author);
-        Assert.assertEquals(author.getNomenclaturalTitle(), speciesName.getAuthorshipCache());
+        Assert.assertEquals(author.getNomenclaturalTitleCache(), speciesName.getAuthorshipCache());
         Assert.assertEquals("Should be Abies alba L.", "Abies alba L.", speciesName.getTitleCache());
 
         speciesName.setBinomHybrid(true);
-        //Note: This test may fail if aspectj doesn't work correctly
+        speciesName.setTitleCache(null, false);
         Assert.assertEquals("Should be Abies \u00D7alba L.", "Abies \u00D7alba L.", speciesName.getTitleCache());
         speciesName.setMonomHybrid(true);
+        speciesName.setTitleCache(null, false);
         Assert.assertEquals("Should be '\u00D7Abies \u00D7alba L.'", "\u00D7Abies \u00D7alba L.", speciesName.getTitleCache());
 
         Assert.assertEquals("Should be 'Genus'", "Genus", genusName.getTitleCache());
         genusName.setMonomHybrid(true);
+        genusName.setTitleCache(null, false);
         Assert.assertEquals("Should be '\u00D7Genus'", "\u00D7Genus", genusName.getTitleCache());
 
         Assert.assertEquals("Should be 'Abies alba subsp. beta'", subSpeciesNameString, subSpeciesName.getTitleCache());
         subSpeciesName.setTrinomHybrid(true);
+        subSpeciesName.setTitleCache(null, false);
         Assert.assertEquals("Should be 'Abies alba nothosubsp. beta or nbeta'", "Abies alba nothosubsp. beta", subSpeciesName.getTitleCache());
         subSpeciesName.setMonomHybrid(true);
+        subSpeciesName.setTitleCache(null, false);
         Assert.assertEquals("Should be '\u00D7Abies alba nothosubsp. beta'", "\u00D7Abies alba nothosubsp. beta", subSpeciesName.getTitleCache());
 
         Assert.assertEquals("Should be 'Genus subg. InfraGenericPart'", "Genus subg. InfraGenericPart", subGenusName.getTitleCache());
         subGenusName.setBinomHybrid(true);
+        subGenusName.setTitleCache(null, false);
         Assert.assertEquals("Should be 'Genus nothosubg. InfraGenericPart'", "Genus nothosubg. InfraGenericPart", subGenusName.getTitleCache());
     }
 
     @Test
     public void testHybridFormula(){
         this.speciesName.setCombinationAuthorship(author);
-        Assert.assertEquals(author.getNomenclaturalTitle(), speciesName.getAuthorshipCache());
+        Assert.assertEquals(author.getNomenclaturalTitleCache(), speciesName.getAuthorshipCache());
         Assert.assertEquals("Should be 'Abies alba L.'", "Abies alba L.", speciesName.getTitleCache());
 
         INonViralName hybridName = TaxonNameFactory.NewNonViralInstance(Rank.SPECIES());
@@ -271,10 +291,148 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         secondParent.setSpecificEpithet("parent");
         hybridName.setNameCache(null, false);
         Assert.assertEquals("", "Abies alba \u00D7 Second parent", hybridName.getNameCache());
+    }
+
+    //#9778
+    @Test
+    public void testOldRanks(){
+
+        //grex
+        subSpeciesName.setRank(Rank.GREX_INFRASPEC());
+        Assert.assertEquals("Abies alba grex beta", strategy.getTitleCache(subSpeciesName));
+        //subgrex
+        subSpeciesName.setRank(Rank.SUBGREX());
+        Assert.assertEquals("Abies alba subgrex beta", strategy.getTitleCache(subSpeciesName));
+        //proles
+        subSpeciesName.setRank(Rank.PROLES());
+        Assert.assertEquals("Abies alba proles beta", strategy.getTitleCache(subSpeciesName));
+        //proles
+        subSpeciesName.setRank(Rank.SUBPROLES());
+        Assert.assertEquals("Abies alba subproles beta", strategy.getTitleCache(subSpeciesName));
+        //lusus
+        subSpeciesName.setRank(Rank.LUSUS());
+        Assert.assertEquals("Abies alba lusus beta", strategy.getTitleCache(subSpeciesName));
+        //sublusus
+        subSpeciesName.setRank(Rank.SUBLUSUS());
+        Assert.assertEquals("Abies alba sublusus beta", strategy.getTitleCache(subSpeciesName));
+    }
+
+    @Test
+    public void testWithoutRank() {
+        subSpeciesName.setRank(null);
+        Assert.assertEquals("Abies alba beta", strategy.getTitleCache(subSpeciesName));
+
+        subSpeciesName.setTrinomHybrid(true);
+        //Not sure if selfstanding notho is correct here, for now only to indicate that there is the hybridflag set
+        //TODO still misses for binom, and monom Hybridflag.
+        Assert.assertEquals("Abies alba notho beta", strategy.getTitleCache(subSpeciesName));
+    }
+
+    //#9754
+    @Test
+    public void testCultivar(){
+
+        //cultivar
+        speciesName.setRank(Rank.CULTIVAR());
+        speciesName.setCultivarEpithet("Cultus");
+        Assert.assertEquals("Abies alba 'Cultus'", strategy.getTitleCache(speciesName));
+
+        speciesName.setBinomHybrid(true);
+        Assert.assertEquals("Abies \u00D7alba 'Cultus'", strategy.getTitleCache(speciesName));
+
+        speciesName.setBinomHybrid(false);
+        speciesName.setSpecificEpithet(null);
+        Assert.assertEquals("Abies 'Cultus'", strategy.getTitleCache(speciesName));
+
+        speciesName.setCombinationAuthorship(author);
+        Assert.assertEquals("Abies 'Cultus' L.", strategy.getTitleCache(speciesName));
+        speciesName.setBasionymAuthorship(basAuthor);
+        speciesName.setExCombinationAuthorship(exAuthor);
+        speciesName.setExBasionymAuthorship(exBasAuthor);
+        Assert.assertEquals("Basionym and ex-authors should not be considered for cultivar names"
+                , "Abies 'Cultus' L.", strategy.getTitleCache(speciesName));
+        speciesName.setNomenclaturalReference(citationRef);
+        Assert.assertEquals("Abies 'Cultus' L., My Reference", strategy.getFullTitleCache(speciesName));
+        speciesName.setCombinationAuthorship(null);
+        speciesName.setBasionymAuthorship(null);
+        speciesName.setExCombinationAuthorship(null);
+        speciesName.setExBasionymAuthorship(null);
+        speciesName.setNomenclaturalReference(null);
+
+        speciesName.setCultivarEpithet(null);
+        Assert.assertEquals("Correct formatting for incorrect name needs to be discussed", "Abies ''", strategy.getTitleCache(speciesName));
+
+        //cultivar group
+        speciesName.setRank(Rank.CULTIVARGROUP());
+        Assert.assertEquals("Abies Group", strategy.getTitleCache(speciesName)); //not sure if this is correct for an empty group field
+        speciesName.setCultivarGroupEpithet("Cultus Group");
+        Assert.assertEquals("Abies Cultus Group", strategy.getTitleCache(speciesName));
+
+        speciesName.setCultivarGroupEpithet("Cultus Gruppe");
+        Assert.assertEquals("Abies Cultus Gruppe", strategy.getTitleCache(speciesName));
+        speciesName.setCultivarGroupEpithet("Cultus Gp");
+        Assert.assertEquals("Abies Cultus Gp", strategy.getTitleCache(speciesName));
+        speciesName.setCultivarGroupEpithet("Gruppo Cultus");
+        Assert.assertEquals("Abies Gruppo Cultus", strategy.getTitleCache(speciesName));
+        speciesName.setCultivarGroupEpithet("Druppo Cultus");
+        Assert.assertEquals("Abies Druppo Cultus Group", strategy.getTitleCache(speciesName));
+        speciesName.setCultivarGroupEpithet(null);
+        Assert.assertEquals("Correct formatting for missing epithet needs to be discussed", "Abies Group", strategy.getTitleCache(speciesName));
+
+        //grex
+        speciesName.setRank(Rank.GREX_ICNCP());
+        speciesName.setCultivarGroupEpithet("Lovely");
+        Assert.assertEquals("Abies Lovely grex", strategy.getTitleCache(speciesName));
+        speciesName.setCultivarGroupEpithet(null);
+        Assert.assertEquals("Correct formatting for missing epithet needs to be discussed", "Abies grex", strategy.getTitleCache(speciesName));
+
+        //subspecies name
+        subSpeciesName.setRank(Rank.CULTIVAR());
+        subSpeciesName.setCultivarEpithet("Cultus");
+        Assert.assertEquals("Infraspecific epithet in cultivars can not be handled correctly yet", "Abies alba beta 'Cultus'", strategy.getTitleCache(subSpeciesName));
+        subSpeciesName.setInfraSpecificEpithet("var. beta");
+        Assert.assertEquals("Abies alba var. beta 'Cultus'", strategy.getTitleCache(subSpeciesName));
+
+
+        //graft chimaera
+        //https://en.wikipedia.org/wiki/Graft-chimaera
+        //either formula (like hybrids) concatenated by ' + ' (Art. 24.2)
+        speciesName.setRank(Rank.GRAFTCHIMAERA());
+        speciesName.setGenusOrUninomial("Laburnocytisus");
+        speciesName.setCultivarEpithet("Adamii");
+        Assert.assertEquals("+ Laburnocytisus 'Adamii'", strategy.getTitleCache(speciesName));
+        //tbc
+
+        //denomination class (only dummy implementation, may change in future)
+        speciesName.setRank(Rank.DENOMINATIONCLASS());
+        speciesName.setGenusOrUninomial("Laburnocytisus");
+        speciesName.setCultivarEpithet("Adamii");
+        Assert.assertEquals("Laburnocytisus 'Adamii'", strategy.getTitleCache(speciesName));
+
+        //appended phrase
+        speciesName.setRank(Rank.CULTIVAR());
+        speciesName.setGenusOrUninomial("Abies");
+        speciesName.setSpecificEpithet("alba");
+        speciesName.setCultivarEpithet("Cultus");
+        speciesName.setAppendedPhrase("appended");
+        Assert.assertEquals("Abies alba 'Cultus' appended", strategy.getTitleCache(speciesName));
+    }
+
+    //10299
+    @Test
+    public void testVerbatimDate() {
 
+        subSpeciesName.setNomenclaturalReference(citationRef);
+        Assert.assertEquals(subSpeciesNameString + ", " +  referenceTitle, subSpeciesName.getFullTitleCache());
+        subSpeciesName.setNomenclaturalMicroReference("25");
+        Assert.assertEquals(subSpeciesNameString + ", " +  referenceTitle + ": 25", subSpeciesName.getFullTitleCache());
+        VerbatimTimePeriod datePublished = TimePeriodParser.parseStringVerbatim("1988");
+        datePublished.setVerbatimDate("1989");
+        citationRef.setDatePublished(datePublished);
+        subSpeciesName.setFullTitleCache(null, false);
+        Assert.assertEquals(subSpeciesNameString + ", " +  referenceTitle + ": 25. 1988 [\"1989\"]", subSpeciesName.getFullTitleCache());
     }
 
-    //TODO add more tests when specification is clearer
     //3665
     @Test
     public void testOriginalSpelling() {
@@ -290,13 +448,36 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         Assert.assertEquals("Name cache should not show original spelling", "Abies alba", speciesName.getNameCache());
 
        originalName.setGenusOrUninomial("Apies");
-       speciesName.setNameCache(null, false);
+       speciesName.setFullTitleCache(null, false);
+       originalName.setNameCache(null, false);
        //TODO update cache of current name (species name)
        Assert.assertEquals("Abies alba [as \"Apies alpa\"]", speciesName.getFullTitleCache());
         Assert.assertEquals("Abies alba", speciesName.getTitleCache());
         Assert.assertEquals("Name cache should not show original spelling", "Abies alba", speciesName.getNameCache());
+        originalName.setSpecificEpithet("alba");
+        originalName.setNameCache(null, false);
+        speciesName.setFullTitleCache(null, false);
+        //not fully sure if it is wanted that here only the genus name is given and not the specific epithet too, may change if required by users
+        Assert.assertEquals("Abies alba [as \"Apies\"]", speciesName.getFullTitleCache());
+
+        //subspecies
+        originalName = subSpeciesName.clone();
+        originalName.setInfraSpecificEpithet("peta");
+        Assert.assertEquals("Preconditions are wrong", "Abies alba subsp. peta", originalName.getTitleCache());
+        subSpeciesName.setOriginalSpelling(originalName);
+        Assert.assertEquals("Abies alba subsp. beta [as \"peta\"]", subSpeciesName.getFullTitleCache());
+        Assert.assertEquals("Abies alba subsp. beta", subSpeciesName.getTitleCache());
+        originalName.setSpecificEpithet("alpa");
+        originalName.setNameCache(null, false);
+        subSpeciesName.setFullTitleCache(null, false);
+        Assert.assertEquals("Abies alba subsp. beta [as \"alpa subsp. peta\"]", subSpeciesName.getFullTitleCache());
+
+        originalName.setInfraSpecificEpithet("beta");
+        originalName.setNameCache(null, false);
+        subSpeciesName.setFullTitleCache(null, false);
+        //not fully sure if it is wanted that here only the specific epithet is given and not the infra specific epithet too, may change if required by users
+        Assert.assertEquals("Abies alba subsp. beta [as \"alpa\"]", subSpeciesName.getFullTitleCache());
 
-       //#3665
        INonViralName correctName = NonViralNameParserImpl.NewInstance().parseFullName("Nepenthes glabrata J.R.Turnbull & A.T.Middleton");
        TaxonName originalSpelling = (TaxonName)NonViralNameParserImpl.NewInstance().parseFullName("Nepenthes glabratus");
        correctName.setOriginalSpelling(originalSpelling);
@@ -314,8 +495,42 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         correctName.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ILLEGITIMATE()));
         correctName.setFullTitleCache(null, false);
         Assert.assertEquals("Nepenthes glabrata J.R.Turnbull & A.T.Middleton, Sp. Pl. 1988 [as \"glabratus\"], nom. illeg.", correctName.getFullTitleCache());
+    }
 
-       //TODO add more tests when specification of exact behaviour is clearer
+    //3667
+    @Test
+    public void testOriginalSpellingItalics() {
+
+        TaxonName originalName = subSpeciesName.clone();
+        originalName.setSpecificEpithet("alpa");
+        Assert.assertEquals("Preconditions are wrong", "Abies alpa subsp. beta", originalName.getTitleCache());
+
+        subSpeciesName.setOriginalSpelling(originalName);
+
+        List<TaggedText> taggedFullTitle = subSpeciesName.cacheStrategy().getTaggedFullTitle(subSpeciesName);
+        Assert.assertEquals(7, taggedFullTitle.size());
+        Assert.assertEquals(new TaggedText(TagEnum.name, "Abies"), taggedFullTitle.get(0));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "alba"), taggedFullTitle.get(1));
+        Assert.assertEquals(new TaggedText(TagEnum.rank, "subsp."), taggedFullTitle.get(2));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "beta"), taggedFullTitle.get(3));
+        Assert.assertEquals(new TaggedText(TagEnum.separator, " [as \""), taggedFullTitle.get(4));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "alpa"), taggedFullTitle.get(5));
+        Assert.assertEquals(new TaggedText(TagEnum.separator, "\"]"), taggedFullTitle.get(6));
+
+        originalName.setInfraSpecificEpithet("peta");
+        originalName.setNameCache(null, false);
+        taggedFullTitle = subSpeciesName.cacheStrategy().getTaggedFullTitle(subSpeciesName);
+        Assert.assertEquals(9, taggedFullTitle.size());
+        Assert.assertEquals(new TaggedText(TagEnum.name, "alba"), taggedFullTitle.get(1));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "Abies"), taggedFullTitle.get(0));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "alba"), taggedFullTitle.get(1));
+        Assert.assertEquals(new TaggedText(TagEnum.rank, "subsp."), taggedFullTitle.get(2));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "beta"), taggedFullTitle.get(3));
+        Assert.assertEquals(new TaggedText(TagEnum.separator, " [as \""), taggedFullTitle.get(4));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "alpa"), taggedFullTitle.get(5));
+        Assert.assertEquals(new TaggedText(TagEnum.rank, "subsp."), taggedFullTitle.get(6));
+        Assert.assertEquals(new TaggedText(TagEnum.name, "peta"), taggedFullTitle.get(7));
+        Assert.assertEquals(new TaggedText(TagEnum.separator, "\"]"), taggedFullTitle.get(8));
     }
 
     @Test
@@ -347,7 +562,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         Assert.assertEquals("Expected full title cache has error", "Abies alba (Basio, A.) L., GenericRef", subSpeciesName.getFullTitleCache());
 
         //author change
-        author.setNomenclaturalTitle("M.");
+        author.setNomenclaturalTitleCache("M.", true);
         Assert.assertEquals("Expected full title cache has error", "(Basio, A.) M.", subSpeciesName.getAuthorshipCache());
         Assert.assertEquals("Expected full title cache has error", "Abies alba (Basio, A.) M., GenericRef", subSpeciesName.getFullTitleCache());
         Assert.assertEquals("Expected full title cache has error", "Abies alba (Basio, A.) M.", subSpeciesName.getTitleCache());
@@ -395,7 +610,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         subSpeciesName.setAuthorshipCache("Ciard.");
         Assert.assertEquals("Expected full title cache has error", "P. alba subsp. beta Ciard., GenericRef", subSpeciesName.getFullTitleCache());
 
-        author.setNomenclaturalTitle("X.");
+        author.setNomenclaturalTitleCache("X.", true);
         subSpeciesName.setProtectedAuthorshipCache(false);
         Assert.assertEquals("Expected full title cache has error", "P. alba subsp. beta (Basio, A.) X., GenericRef", subSpeciesName.getFullTitleCache());
 
@@ -410,6 +625,9 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         Assert.assertEquals("Expected full title cache has error", "A. alba subsp. beta (Basio, A.) X., GenericRef", subSpeciesName.getFullTitleCache());
         subSpeciesName.setProtectedNameCache(false);
         Assert.assertEquals("Expected full title cache has error", "A. alba subsp. beta app phrase (Basio, A.) X., GenericRef", subSpeciesName.getFullTitleCache());
+        subSpeciesName.setAppendedPhrase("[\"app phrase\"]");
+        Assert.assertEquals("Expected full title cache has error", "A. alba subsp. beta [\"app phrase\"] (Basio, A.) X., GenericRef", subSpeciesName.getFullTitleCache());
+
         subSpeciesName.setAppendedPhrase("app2 phrase2");
         subSpeciesName.setProtectedNameCache(true);
         Assert.assertNull("NameCache should be null", subSpeciesName.getNameCache());
@@ -504,7 +722,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         nonViralName.setAuthorshipCache(author);
 
         //test ordinary infrageneric
-        List<TaggedText> subGenusNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
+        List<TaggedText> subGenusNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName, false);
         String subGenusNameCache = TaggedCacheHelper.createString(subGenusNameCacheTagged);
         assertEquals("Subgenus name should be 'Genus subg. subgenus'.", "Genus subg. subgenus", subGenusNameCache);
         String subGenusTitle = strategy.getTitleCache(nonViralName);
@@ -516,7 +734,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         nonViralName.setInfraGenericEpithet(null);
         nonViralName.setAuthorshipCache(null);
 
-        List<TaggedText> aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
+        List<TaggedText> aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName, false);
 
         String aggrNameCache = TaggedCacheHelper.createString(aggrNameCacheTagged);
         assertEquals("Species aggregate name should be 'Genus myspecies aggr.'.", "Genus myspecies aggr.", aggrNameCache);
@@ -533,7 +751,7 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         nonViralName.setSpecificEpithet("myspecies");
         nonViralName.setInfraGenericEpithet("Infragenus");
 
-        aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
+        aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName, false);
         aggrNameCache = TaggedCacheHelper.createString(aggrNameCacheTagged);
         assertEquals("Species aggregate name should be 'Genus (Infragenus) myspecies aggr.'.", "Genus (Infragenus) myspecies aggr.", aggrNameCache);
 
@@ -620,4 +838,61 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         String expected = String.format("Ophrys %skastelli E. Klein nothosubsp. kastelli", UTF8.HYBRID.toString());
         Assert.assertEquals("", expected, name.getTitleCache());
     }
+
+    @Test
+    public void testEtAlAuthors() {
+        TaxonName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
+        name.setGenusOrUninomial("Ophrys");
+        name.setSpecificEpithet("kastelli");
+        Team combTeam = Team.NewInstance();
+        combTeam.addTeamMember(Person.NewInstance("Mill.", "Miller", "A.", null));
+        combTeam.addTeamMember(Person.NewInstance("Ball.", "Baller", "B.", null));
+        combTeam.addTeamMember(Person.NewInstance("Cill.", "Ciller", "C.", null));
+        name.setCombinationAuthorship(combTeam);
+
+        INameCacheStrategy formatter = name.cacheStrategy();
+        Assert.assertEquals("", "Ophrys kastelli Mill., Ball. & Cill.", formatter.getTitleCache(name));
+        formatter.setEtAlPosition(3);
+        Assert.assertEquals("", "Ophrys kastelli Mill., Ball. & Cill.", formatter.getTitleCache(name));
+        formatter.setEtAlPosition(2);
+        Assert.assertEquals("", "Ophrys kastelli Mill. & al.", formatter.getTitleCache(name));
+        //null and <2 are handled as "no position defined"
+        formatter.setEtAlPosition(1);
+        Assert.assertEquals("", "Ophrys kastelli Mill., Ball. & Cill.", formatter.getTitleCache(name));
+        formatter.setEtAlPosition(null);
+        Assert.assertEquals("", "Ophrys kastelli Mill., Ball. & Cill.", formatter.getTitleCache(name));
+
+        name.setBasionymAuthorship(combTeam);
+        formatter.setEtAlPosition(2);
+        Assert.assertEquals("", "Ophrys kastelli (Mill. & al.) Mill. & al.", formatter.getTitleCache(name));
+
+    }
+
+    @Test  //#7443
+    public void testInAuthors() {
+        //base configuration
+        speciesName.setCombinationAuthorship(author);
+        speciesName.setBasionymAuthorship(basAuthor);
+        String expectedWithoutInAuthor = speciesNameString + " (" + basAuthorString + ") " + authorString;
+        Assert.assertEquals(expectedWithoutInAuthor, speciesName.getTitleCache());
+
+        //with in-authors
+        speciesName.setNameType(NomenclaturalCode.Fungi);
+        speciesName.setInBasionymAuthorship(inBasAuthor);
+        speciesName.setInCombinationAuthorship(inAuthor);
+        String expectedWithInAuthor = speciesNameString + " (" + basAuthorString + " in "+inBasAuthorString+") " + authorString + " in "+inAuthorString;
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals(expectedWithInAuthor, speciesName.getTitleCache());
+
+        //... for zoo-names
+        speciesName.setNameType(NomenclaturalCode.ICZN);
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals(expectedWithInAuthor, speciesName.getTitleCache());
+
+        //... for botanical names
+        speciesName.setNameType(NomenclaturalCode.ICNAFP);
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals("For now we do not allow in-authors for botanical names (except for fungi)",
+                expectedWithoutInAuthor, speciesName.getTitleCache());
+    }
 }
\ No newline at end of file