Project

General

Profile

Download (199 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.strategy.parser;
10

    
11
import static org.junit.Assert.assertEquals;
12
import static org.junit.Assert.assertFalse;
13
import static org.junit.Assert.assertNotNull;
14
import static org.junit.Assert.assertNull;
15
import static org.junit.Assert.assertTrue;
16

    
17
import java.lang.reflect.InvocationTargetException;
18
import java.lang.reflect.Method;
19
import java.util.List;
20
import java.util.regex.Matcher;
21
import java.util.regex.Pattern;
22

    
23
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
24
import org.joda.time.DateTime;
25
import org.joda.time.Duration;
26
import org.junit.Assert;
27
import org.junit.Before;
28
import org.junit.Ignore;
29
import org.junit.Test;
30

    
31
import eu.etaxonomy.cdm.common.UTF8;
32
import eu.etaxonomy.cdm.model.agent.Person;
33
import eu.etaxonomy.cdm.model.agent.Team;
34
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
35
import eu.etaxonomy.cdm.model.common.TimePeriod;
36
import eu.etaxonomy.cdm.model.name.HybridRelationship;
37
import eu.etaxonomy.cdm.model.name.IBotanicalName;
38
import eu.etaxonomy.cdm.model.name.INonViralName;
39
import eu.etaxonomy.cdm.model.name.IZoologicalName;
40
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
41
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
42
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
43
import eu.etaxonomy.cdm.model.name.Rank;
44
import eu.etaxonomy.cdm.model.name.TaxonName;
45
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
46
import eu.etaxonomy.cdm.model.reference.IArticle;
47
import eu.etaxonomy.cdm.model.reference.IBook;
48
import eu.etaxonomy.cdm.model.reference.IBookSection;
49
import eu.etaxonomy.cdm.model.reference.IJournal;
50
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
51
import eu.etaxonomy.cdm.model.reference.IVolumeReference;
52
import eu.etaxonomy.cdm.model.reference.Reference;
53
import eu.etaxonomy.cdm.model.reference.ReferenceType;
54
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
55
import eu.etaxonomy.cdm.test.TermTestBase;
56

    
57
/**
58
 * Tests for {@link NonViralNameParserImpl}.
59
 *
60
 * @author a.mueller
61
 */
62
public class NonViralNameParserImplTest extends TermTestBase {
63

    
64
    private static final NomenclaturalCode ICNAFP = NomenclaturalCode.ICNAFP;
65
    private static final NomenclaturalCode ICZN = NomenclaturalCode.ICZN;
66

    
67
    private static final String SEP = TimePeriod.SEP;
68

    
69
    private static final Logger logger = LogManager.getLogger(NonViralNameParserImplTest.class);
70

    
71
    final private String strNameAbies1 = "Abies alba";
72
    final private String strNameAbiesSub1 = "Abies alba subsp. beta";
73
    final private String strNameAbiesAuthor1 = "Abies alba Mueller";
74
    final private String strNameAbiesAuthor1Unicode = "Abies alba M\u00FCller";
75
    final private String strNameAbiesBasionymAuthor1 = "Abies alba (Ciardelli) D'Mueller";
76
    final private String strNameAbiesBasionymAuthor1Unicode = "Abies alba (Ciardelli) D'M\u00FCller";
77
    final private String strNameAbiesBasionymExAuthor1 ="Abies alba (Ciardelli ex Doering) D'Mueller ex. de Greuther";
78
    final private String strNameAbiesBasionymExAuthor1Unicode ="Abies alba (Ciardelli ex D\u00F6ring) D'M\u00FCller ex. de Greuther";
79
    final private String strNameTeam1 = "Abies alba Mueller & L.";
80
    final private String strNameZoo1 = "Abies alba Mueller & L., 1822";
81
    final private String strNameZoo2 = "Abies alba (Mueller, 1822) Ciardelli, 2002";
82
    final private String strNameZoo3 = "Marmota marmota normalis Ciardelli, 2002";
83
    final private String strNameZoo4 = "Marmota marmota subsp. normalis Ciardelli, 2002";
84
    final private String strNameZoo5 = "Marmota marmota var. normalis Ciardelli, 2002";
85

    
86
    final private String strNameEmpty = "";
87
    final private String strNameNull = null;
88

    
89
    private NonViralNameParserImpl parser ;
90
    private NomenclaturalCode botanicCode;
91

    
92
    @Before
93
    public void setUp() throws Exception {
94
        parser = NonViralNameParserImpl.NewInstance();
95
        botanicCode = ICNAFP;
96
    }
97

    
98
/*************** TEST *********************************************/
99

    
100
    @Test
101
    public final void testNewInstance() {
102
        assertNotNull(parser);
103
    }
104

    
105
    @Test
106
    public final void testTaxonNameParserBotanicalNameImpl() {
107
        logger.warn("Not yet implemented"); // TODO
108
    }
109

    
110
    @Test
111
    public final void testTeamSeperation(){
112
        Rank speciesRank = Rank.SPECIES();
113
        INonViralName name;
114

    
115
//      String strNameWith1AUthorAndCommaSepEditon = "Abies alba Mill., Sp. Pl., ed. 3: 455. 1987";
116
//      name = parser.parseReferencedName(strNameWith1AUthorAndCommaSepEditon, botanicCode, speciesRank);
117
//      Assert.assertFalse("No problems should exist", name.hasProblem());
118
//      Assert.assertEquals("Name should not include reference part", "Abies alba Mill.", name.getTitleCache());
119
//      Assert.assertEquals("Mill., Sp. Pl., ed. 3. 1987", name.getNomenclaturalReference().getTitleCache());
120
//
121
//
122
//      String strNameWith2Authors = "Abies alba L. & Mill., Sp. Pl., ed. 3: 455. 1987";
123
//      name = parser.parseReferencedName(strNameWith2Authors, botanicCode, speciesRank);
124
//      Assert.assertFalse("No problems should exist", name.hasProblem());
125
//      Assert.assertEquals("Name should not include reference part", "Abies alba L. & Mill.", name.getTitleCache());
126
//      Assert.assertEquals("Name should have authorteam with 2 authors", 2, ((Team)name.getCombinationAuthorship()).getTeamMembers().size());
127
//      Assert.assertEquals("L. & Mill., Sp. Pl., ed. 3. 1987", name.getNomenclaturalReference().getTitleCache());
128

    
129
        String strNameWith3Authors = "Abies alba Mess., L. & Mill., Sp. Pl., ed. 3: 455. 1987";
130
        name = parser.parseReferencedName(strNameWith3Authors, botanicCode, speciesRank);
131
        Assert.assertFalse("No problems should exist", name.hasProblem());
132
        Assert.assertEquals("Name should not include reference part", "Abies alba Mess., L. & Mill.", name.getTitleCache());
133
        Assert.assertEquals("Name should have authorship with 2 authors", 3, ((Team)name.getCombinationAuthorship()).getTeamMembers().size());
134
        Assert.assertEquals("Mess., L. & Mill. 1987: Sp. Pl., ed. 3", name.getNomenclaturalReference().getTitleCache());
135
    }
136

    
137
    @Test
138
    public final void testParseSimpleName() {
139

    
140
        //Uninomials
141
        IZoologicalName milichiidae = (IZoologicalName)parser.parseSimpleName("Milichiidae", NomenclaturalCode.ICZN, null);
142
        assertEquals("Family rank expected", Rank.FAMILY(), milichiidae.getRank());
143
        IBotanicalName crepidinae = (IBotanicalName)parser.parseSimpleName("Crepidinae", ICNAFP, null);
144
        assertEquals("Family rank expected", Rank.SUBTRIBE(), crepidinae.getRank());
145
        IBotanicalName abies = (IBotanicalName)parser.parseSimpleName("Abies", ICNAFP, null);
146
        assertEquals("Family rank expected", Rank.GENUS(), abies.getRank());
147

    
148
        abies.addParsingProblem(ParserProblem.CheckRank);
149
        parser.parseSimpleName(abies, "Abies", abies.getRank(), true);
150
        assertTrue(abies.getParsingProblems().contains(ParserProblem.CheckRank));
151

    
152
        IBotanicalName rosa = (IBotanicalName)parser.parseSimpleName("Rosaceae", ICNAFP, null);
153
        assertTrue("Rosaceae have rank family", rosa.getRank().equals(Rank.FAMILY()));
154
        assertTrue("Rosaceae must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
155
        parser.parseSimpleName(rosa, "Rosaceaex", abies.getRank(), true);
156
        assertEquals("Rosaceaex have rank genus", Rank.GENUS(), rosa.getRank());
157
        assertTrue("Rosaceaex must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
158

    
159
        //repeat but remove warning after first parse
160
        rosa = (IBotanicalName)parser.parseSimpleName("Rosaceae", ICNAFP, null);
161
        assertTrue("Rosaceae have rank family", rosa.getRank().equals(Rank.FAMILY()));
162
        assertTrue("Rosaceae must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
163
        rosa.removeParsingProblem(ParserProblem.CheckRank);
164
        parser.parseSimpleName(rosa, "Rosaceaex", rosa.getRank(), true);
165
        assertEquals("Rosaceaex have rank family", Rank.FAMILY(), rosa.getRank());
166
        assertFalse("Rosaceaex must have no rank warning", rosa.hasProblem(ParserProblem.CheckRank));
167
    }
168

    
169
    @Test
170
    public final void testParseSubGenericFullName() {
171
        String zooSpeciesWithSubgenus = "Bacanius (Mullerister) rombophorus (Aube, 1843)";
172
        //zoo as fullName
173
        IZoologicalName zooName = parser.parseReferencedName(zooSpeciesWithSubgenus, NomenclaturalCode.ICZN, Rank.SPECIES());
174
        Assert.assertTrue(zooName.getParsingProblems().isEmpty());
175
        Assert.assertEquals("Mullerister", zooName.getInfraGenericEpithet());
176
        Assert.assertEquals(Integer.valueOf(1843), zooName.getOriginalPublicationYear());
177
        //zoo as referenced name
178
        zooName = (IZoologicalName)parser.parseFullName(zooSpeciesWithSubgenus, NomenclaturalCode.ICZN, Rank.SPECIES());
179
        Assert.assertTrue(zooName.getParsingProblems().isEmpty());
180
        Assert.assertEquals("Mullerister", zooName.getInfraGenericEpithet());
181
        Assert.assertEquals(Integer.valueOf(1843), zooName.getOriginalPublicationYear());
182

    
183
        //bot as full Name
184
        String botSpeciesWithSubgenus = "Bacanius (Mullerister) rombophorus (Aube) Mill.";
185
        IBotanicalName botName = (IBotanicalName)parser.parseFullName(botSpeciesWithSubgenus, NomenclaturalCode.ICNAFP, Rank.GENUS());
186
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
187
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
188
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
189
        Assert.assertEquals("Aube", botName.getBasionymAuthorship().getTitleCache());
190

    
191
        //bot as referenced Name
192
        botName = parser.parseReferencedName(botSpeciesWithSubgenus, NomenclaturalCode.ICNAFP, Rank.GENUS());
193
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
194
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
195
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
196
        Assert.assertEquals("Aube", botName.getBasionymAuthorship().getTitleCache());
197

    
198
        //bot without author
199
        String botSpeciesWithSubgenusWithoutAuthor = "Bacanius (Mullerister) rombophorus";
200
        botName = parser.parseReferencedName(botSpeciesWithSubgenusWithoutAuthor, NomenclaturalCode.ICNAFP, Rank.GENUS());
201
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
202
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
203
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
204
        Assert.assertEquals("", botName.getAuthorshipCache());
205
    }
206

    
207
    @Test
208
    public final void testParseSubGenericSimpleName() {
209
        logger.warn("Not yet implemented"); // TODO
210
    }
211

    
212
    @Test
213
    public final void testParseFullNameUnicode() {
214

    
215
        INonViralName nameAuthor = parser.parseFullName(strNameAbiesAuthor1Unicode, null, Rank.SPECIES());
216
        assertEquals("Abies", nameAuthor.getGenusOrUninomial());
217
        assertEquals("alba", nameAuthor.getSpecificEpithet());
218
        assertEquals("M\u00FCller", nameAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
219

    
220
        INonViralName nameBasionymAuthor = parser.parseFullName(strNameAbiesBasionymAuthor1Unicode, null, Rank.SPECIES());
221
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
222
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
223
        assertEquals("D'M\u00FCller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
224
        TeamOrPersonBase<?> basionymTeam = nameBasionymAuthor.getBasionymAuthorship();
225
        assertEquals("Ciardelli", basionymTeam.getNomenclaturalTitleCache());
226

    
227
        INonViralName nameBasionymExAuthor = parser.parseFullName(strNameAbiesBasionymExAuthor1Unicode, null, Rank.SPECIES());
228
        assertEquals("Abies", nameBasionymExAuthor.getGenusOrUninomial());
229
        assertEquals("alba", nameBasionymExAuthor.getSpecificEpithet());
230
        assertEquals("D'M\u00FCller", nameBasionymExAuthor.getExCombinationAuthorship().getNomenclaturalTitleCache());
231
        assertEquals("de Greuther", nameBasionymExAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
232
        TeamOrPersonBase<?> basionymTeam2 = nameBasionymExAuthor.getExBasionymAuthorship();
233
        assertEquals("Ciardelli", basionymTeam2.getNomenclaturalTitleCache());
234
        TeamOrPersonBase<?> exBasionymTeam2 = nameBasionymExAuthor.getBasionymAuthorship();
235
        assertEquals("D\u00F6ring", exBasionymTeam2.getNomenclaturalTitleCache());
236

    
237
        IBotanicalName nameBasionymExAuthor2 = (IBotanicalName)parser.parseFullName("Washingtonia filifera (Linden ex Andre) H.Wendl. ex de Bary", null, Rank.SPECIES());
238
        assertEquals("Washingtonia", nameBasionymExAuthor2.getGenusOrUninomial());
239
        assertEquals("filifera", nameBasionymExAuthor2.getSpecificEpithet());
240
        assertEquals("H.Wendl.", nameBasionymExAuthor2.getExCombinationAuthorship().getNomenclaturalTitleCache());
241
        assertEquals("de Bary", nameBasionymExAuthor2.getCombinationAuthorship().getNomenclaturalTitleCache());
242
        TeamOrPersonBase<?> basionymTeam3 = nameBasionymExAuthor2.getBasionymAuthorship();
243
        assertEquals("Andre", basionymTeam3.getNomenclaturalTitleCache());
244
        TeamOrPersonBase<?> exBasionymTeam3 = nameBasionymExAuthor2.getExBasionymAuthorship();
245
        assertEquals("Linden", exBasionymTeam3.getNomenclaturalTitleCache());
246
        String title = nameBasionymExAuthor2.getTitleCache();
247
        assertEquals("Washingtonia filifera (Linden ex Andre) H.Wendl. ex de Bary", title);
248
    }
249

    
250
    @Test
251
    public final void testParseFullName() {
252
        try {
253
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
254
            testName_StringNomcodeRank(parseMethod);
255
        } catch (Exception e) {
256
            e.printStackTrace();
257
            assertTrue(false);
258
        }
259

    
260
        //Team
261
        INonViralName nameTeam1 = parser.parseFullName(strNameTeam1);
262
        assertEquals( "Abies", nameTeam1.getGenusOrUninomial());
263
        assertEquals( "alba", nameTeam1.getSpecificEpithet());
264
        assertEquals("Mueller & L.",  nameTeam1.getCombinationAuthorship().getNomenclaturalTitleCache());
265
        assertTrue(nameTeam1.getCombinationAuthorship() instanceof Team);
266
        Team team = (Team)nameTeam1.getCombinationAuthorship();
267
        assertEquals("Mueller", team.getTeamMembers().get(0).getNomenclaturalTitleCache());
268
        assertEquals("L.", team.getTeamMembers().get(1).getNomenclaturalTitleCache());
269

    
270
        //ZooName
271
        IZoologicalName nameZoo1 = (IZoologicalName)parser.parseFullName(strNameZoo1);
272
        assertEquals( "Abies", nameZoo1.getGenusOrUninomial());
273
        assertEquals( "alba", nameZoo1.getSpecificEpithet());
274
        assertEquals("Mueller & L.",  nameZoo1.getCombinationAuthorship().getNomenclaturalTitleCache());
275
        assertEquals(NomenclaturalCode.ICZN, nameZoo1.getNameType() );
276
        assertEquals(Integer.valueOf(1822), nameZoo1.getPublicationYear());
277
        assertTrue(nameZoo1.getCombinationAuthorship() instanceof Team);
278
        Team teamZoo = (Team)nameZoo1.getCombinationAuthorship();
279
        assertEquals("Mueller", teamZoo.getTeamMembers().get(0).getNomenclaturalTitleCache());
280
        assertEquals("L.", teamZoo.getTeamMembers().get(1).getNomenclaturalTitleCache());
281

    
282
        IZoologicalName nameZoo2 = (IZoologicalName)parser.parseFullName(strNameZoo2);
283
        assertEquals(Integer.valueOf(2002), nameZoo2.getPublicationYear());
284
        assertEquals(Integer.valueOf(1822), nameZoo2.getOriginalPublicationYear());
285
        assertEquals("Mueller",  nameZoo2.getBasionymAuthorship().getNomenclaturalTitleCache());
286
        assertEquals("Ciardelli",  nameZoo2.getCombinationAuthorship().getNomenclaturalTitleCache());
287

    
288
        //subsp
289
        IZoologicalName nameZoo3 = (IZoologicalName)parser.parseFullName(strNameZoo3);
290
        assertEquals("Ciardelli",  nameZoo3.getCombinationAuthorship().getNomenclaturalTitleCache());
291
        assertFalse("Subsp. without marker should be parsable", nameZoo3.hasProblem());
292
        assertEquals("Variety should be recognized", Rank.SUBSPECIES(), nameZoo3.getRank());
293

    
294
        IZoologicalName nameZoo4 = (IZoologicalName)parser.parseFullName(strNameZoo4);
295
        assertEquals("Ciardelli",  nameZoo4.getCombinationAuthorship().getNomenclaturalTitleCache());
296
        assertFalse("Subsp. without marker should be parsable", nameZoo4.hasProblem());
297
        assertEquals("Variety should be recognized", Rank.SUBSPECIES(), nameZoo4.getRank());
298

    
299
        IZoologicalName nameZoo5 = (IZoologicalName)parser.parseFullName(strNameZoo5);
300
        assertEquals("Ciardelli",  nameZoo5.getCombinationAuthorship().getNomenclaturalTitleCache());
301
        assertFalse("Subsp. without marker should be parsable", nameZoo5.hasProblem());
302
        assertEquals("Variety should be recognized", Rank.VARIETY(), nameZoo5.getRank());
303

    
304
        //empty
305
        INonViralName nameEmpty = parser.parseFullName(strNameEmpty);
306
        assertNotNull(nameEmpty);
307
        assertEquals("", nameEmpty.getTitleCache());
308

    
309
        //null
310
        INonViralName nameNull = parser.parseFullName(strNameNull);
311
        assertNull(nameNull);
312

    
313
        //some authors
314
        String fullNameString = "Abies alba (Greuther & L'Hiver & al. ex M\u00FCller & Schmidt)Clark ex Ciardelli";
315
        INonViralName authorname = parser.parseFullName(fullNameString);
316
        assertFalse(authorname.hasProblem());
317
        assertEquals("Basionym author should have 3 authors", 2, ((Team)authorname.getExBasionymAuthorship()).getTeamMembers().size());
318
        Assert.assertTrue("ExbasionymAuthorship must have more members'", ((Team)authorname.getExBasionymAuthorship()).isHasMoreMembers());
319

    
320
        //author with 2 capitals
321
        fullNameString = "Campanula rhodensis A. DC.";
322
        INonViralName name = parser.parseFullName(fullNameString);
323
        assertFalse(name.hasProblem());
324

    
325
        //author with no space  #5618
326
        fullNameString = "Gordonia moaensis (Vict.)H. Keng";
327
        name = parser.parseFullName(fullNameString);
328
        assertFalse(name.hasProblem());
329
        assertNotNull(name.getCombinationAuthorship());
330
        assertEquals("H. Keng", name.getCombinationAuthorship().getNomenclaturalTitleCache());
331

    
332
        //name without combination  author  , only to check if above fix for #5618 works correctly
333
        fullNameString = "Gordonia moaensis (Vict.)";
334
        name = parser.parseFullName(fullNameString);
335
        assertFalse(name.hasProblem());
336
        assertNull(name.getCombinationAuthorship());
337
        assertNotNull(name.getBasionymAuthorship());
338
        assertEquals("Vict.", name.getBasionymAuthorship().getNomenclaturalTitleCache());
339

    
340
    }
341

    
342
    @Test
343
    public final void testAutonyms(){
344
        TaxonName autonymName;
345
        //infraspecific
346
        autonymName = (TaxonName)parser.parseFullName("Abies alba Mill. var. alba", ICNAFP, null);
347
        assertFalse("Autonym should be parsable", autonymName.hasProblem());
348
        autonymName = parser.parseReferencedName("Abies alba Mill. var. alba", ICNAFP, null);
349
        assertFalse("Autonym should be parsable", autonymName.hasProblem());
350
        //infrageneric
351
        autonymName = (TaxonName)parser.parseFullName("Abies Mill. sect. Abies", ICNAFP, null);
352
        assertFalse("Genus autonym should be parsable", autonymName.hasProblem());
353
        assertEquals("Rank should be section (bot.)", Rank.SECTION_BOTANY(), autonymName.getRank());
354
        autonymName = parser.parseReferencedName("Achnanthes Bory sect. Achnanthes", ICNAFP, null);
355
        assertFalse("Genus autonym should be parsable", autonymName.hasProblem());
356
        assertEquals("Rank should be section (bot.)", Rank.SECTION_BOTANY(), autonymName.getRank());
357
    }
358

    
359
    @Test
360
    public final void testEtAl() throws StringNotParsableException {
361
        //some authors
362
        String fullNameString = "Abies alba Greuther, Hiver & al.";
363
        INonViralName authorname = parser.parseFullName(fullNameString);
364
        assertFalse(authorname.hasProblem());
365
        assertEquals("Basionym author should have 2 authors", 2, ((Team)authorname.getCombinationAuthorship()).getTeamMembers().size());
366
        assertTrue("Basionym author team should have more authors", ((Team)authorname.getCombinationAuthorship()).isHasMoreMembers()  );
367

    
368
        //et al.
369
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
370
        parser.parseAuthors(nvn, "Eckweiler, Hand et al., 2003");
371
        Team team = (Team)nvn.getCombinationAuthorship();
372
        Assert.assertNotNull("Comb. author must not be null", team);
373
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
374
        Assert.assertEquals("Second member must be 'Hand'", "Hand", team.getTeamMembers().get(1).getTitleCache());
375
        Assert.assertTrue("Team must have more members'", team.isHasMoreMembers());
376
    }
377

    
378
    @Test
379
    public final void testMultipleAuthors() {
380
        //multiple authors for inReference
381
        String fullTitleString = "Abies alba L. in Mill., Gregor & Behr., Sp. Pl. 173: 384. 1982.";
382
        INonViralName multipleAuthorRefName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
383
        assertFalse(multipleAuthorRefName.hasProblem());
384
        assertTrue("Combination author should be a person", multipleAuthorRefName.getCombinationAuthorship() instanceof Person);
385
        assertEquals("Combination author should be L.", "L.", ((Person)multipleAuthorRefName.getCombinationAuthorship()).getNomenclaturalTitleCache());
386
        Reference nomRef = multipleAuthorRefName.getNomenclaturalReference();
387
        Assert.assertNotNull("nomRef must have inRef", nomRef.getInReference());
388
        Reference inRef = nomRef.getInReference();
389
        String abbrevTitle = inRef.getAbbrevTitle();
390
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
391
        assertTrue(inRef.getAuthorship() instanceof Team);
392
        Team team = (Team)inRef.getAuthorship();
393
        assertEquals(3, team.getTeamMembers().size());
394

    
395
//        multiple authors in Name
396
        fullTitleString = "Abies alba Mill., Aber & Schwedt";
397
        INonViralName multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
398
        assertFalse(multipleAuthorName.hasProblem());
399
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
400
        team = (Team)multipleAuthorName.getCombinationAuthorship();
401
        assertEquals(3, team.getTeamMembers().size());
402
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
403

    
404
//      multiple authors in Name with reference
405
        fullTitleString = "Abies alba Mill., Aber & Schwedt in L., Sp. Pl. 173: 384. 1982.";
406
        multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
407
        assertFalse(multipleAuthorName.hasProblem());
408
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
409
        team = (Team)multipleAuthorName.getCombinationAuthorship();
410
        assertEquals(3, team.getTeamMembers().size());
411
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
412
        nomRef = multipleAuthorName.getNomenclaturalReference();
413
        Assert.assertNotNull("nomRef must have inRef", nomRef.getInReference());
414
        inRef = nomRef.getInReference();
415
        abbrevTitle = inRef.getAbbrevTitle();
416
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
417
        assertTrue(inRef.getAuthorship() instanceof Person);
418
        Person person = (Person)inRef.getAuthorship();
419
        assertEquals("Book author should be L.", "L.", person.getNomenclaturalTitleCache());
420

    
421

    
422
        fullTitleString = "Abies alba Mill., Aber & Schwedt, Sp. Pl. 173: 384. 1982.";
423
        multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
424
        assertFalse(multipleAuthorName.hasProblem());
425
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
426
        team = (Team)multipleAuthorName.getCombinationAuthorship();
427
        assertEquals(3, team.getTeamMembers().size());
428
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
429
        nomRef = multipleAuthorName.getNomenclaturalReference();
430
        Assert.assertNull("nomRef must not have inRef as it is a book itself", nomRef.getInReference());
431
        abbrevTitle = nomRef.getAbbrevTitle();
432
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
433
        assertTrue(nomRef.getAuthorship() instanceof Team);
434
        team = (Team)nomRef.getAuthorship();
435
        assertEquals(3, team.getTeamMembers().size());
436
        assertEquals("Second team member should be Schwedt", "Schwedt", team.getTeamMembers().get(2).getTitleCache());
437

    
438
        //et al.
439
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
440
        parser.parseReferencedName (nvn, "Marmota marmota Eckweiler, Hand et al., 2003", Rank.SPECIES(),true);
441
        assertTrue("Combination author should be a team", nvn.getCombinationAuthorship() instanceof Team);
442
        team = (Team)nvn.getCombinationAuthorship();
443
        Assert.assertNotNull("Comb. author must not be null", team);
444
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
445
        Assert.assertEquals("Second member must be 'Hand'", "Hand", team.getTeamMembers().get(1).getTitleCache());
446
        Assert.assertTrue("Team must have more members'", team.isHasMoreMembers());
447

    
448
    }
449

    
450
    @Test
451
    public final void testHybrids() {
452
        INonViralName name1;
453

    
454
        //Infrageneric hybrid
455
        name1 = parser.parseFullName("Aegilops nothosubg. Insulae Scholz", botanicCode, null);
456
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
457
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
458
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
459
        assertEquals("Infrageneric epithet must be 'Insulae'", "Insulae", name1.getInfraGenericEpithet());
460

    
461
        //Species hybrid
462
//      INonViralName nameTeam1 = parser.parseFullName("Aegilops \u00D7insulae-cypri H. Scholz");
463
        name1 = parser.parseFullName("Aegilops \u00D7insulae Scholz", botanicCode, null);
464
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
465
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
466
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
467
        assertEquals("Species epithet must be 'insulae'", "insulae", name1.getSpecificEpithet());
468

    
469
        name1 = parser.parseFullName("Aegilops \u00D7 insulae Scholz", botanicCode, null);
470
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
471
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
472
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
473
        assertEquals("Species epithet must be 'insulae'", "insulae", name1.getSpecificEpithet());
474

    
475
        //Uninomial hybrid
476
        name1 = parser.parseFullName("x Aegilops Scholz", botanicCode, null);
477
        assertTrue("Name must have monom hybrid bit set", name1.isMonomHybrid());
478
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
479
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
480
        assertEquals("Uninomial must be 'Aegilops'", "Aegilops", name1.getGenusOrUninomial());
481

    
482
        //Subspecies hybrid with hybrid sign
483
        //maybe false: see https://dev.e-taxonomy.eu/redmine/issues/3868
484
        name1 = parser.parseFullName("Aegilops insulae subsp. X abies Scholz", botanicCode, null);
485
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
486
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
487
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
488
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
489

    
490
        //Subspecies hybrid with notho / n
491
        name1 = parser.parseFullName("Aegilops insulae nothosubsp. abies Scholz", botanicCode, null);
492
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
493
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
494
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
495
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
496
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
497

    
498
        name1 = parser.parseFullName("Aegilops insulae nsubsp. abies Scholz", botanicCode, null);
499
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
500
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
501
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
502
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
503
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
504

    
505
        //
506
        String nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
507
        name1 = parser.parseFullName(nameStr);
508
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
509
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
510
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
511
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
512
        assertEquals(nameStr, name1.getTitleCache());  //we expect the cache strategy to create the same result
513

    
514
        nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
515
        name1 = parser.parseFullName(nameStr);
516
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
517
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
518
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
519
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
520
        assertEquals(nameStr, name1.getTitleCache());  //we expect the cache strategy to create the same result
521

    
522
        //nothovar.
523
        nameStr = "Dactylorhiza incarnata nothovar. versicolor";
524
        name1 = parser.parseFullName(nameStr);
525
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
526
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
527
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
528
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
529
        assertEquals(nameStr, name1.getNameCache());  //we expect the cache strategy to create the same result
530

    
531
        //hybrid autonym #6656
532
        nameStr = "Ophrys \u00D7kastelli E. Klein nothosubsp. kastelli";
533
        name1 = parser.parseFullName(nameStr);
534
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
535
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
536
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
537
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
538
        assertEquals(nameStr, name1.getTitleCache()); //we expect the cache strategy to create the same result
539

    
540
        name1 = parser.parseReferencedName(nameStr);
541
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
542
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
543
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
544
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
545
        assertEquals(nameStr, name1.getTitleCache()); //we expect the cache strategy to create the same result
546

    
547
        //remove space since #7094
548
        parser.setRemoveSpaceAfterDot(true);
549
        name1 = parser.parseReferencedName(nameStr);
550
        assertEquals(nameStr.replace("E. Kl", "E.Kl"), name1.getTitleCache()); //we expect the cache strategy to create the same result
551
        parser.setRemoveSpaceAfterDot(false);
552
    }
553

    
554
    @Test
555
    public final void testHybridFormulars() {
556
        try {
557
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
558
            testName_StringNomcodeRank(parseMethod);
559
        } catch (Exception e) {
560
            e.printStackTrace();
561
            assertTrue(false);
562
        }
563

    
564
        //Species hybrid
565
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
566
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
567
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
568
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
569
        assertEquals("Title cache must be correct", hybridCache, name1.getTitleCache());
570
        List<HybridRelationship> orderedRels = name1.getOrderedChildRelationships();
571
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
572
        TaxonName firstParent = orderedRels.get(0).getParentName();
573
        assertEquals("Name must have Abies alba as first hybrid parent", "Abies alba", firstParent.getTitleCache());
574
        TaxonName secondParent = orderedRels.get(1).getParentName();
575
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
576
        assertEquals("Hybrid name must have the lowest rank ('species') as rank", Rank.SPECIES(), name1.getRank());
577
        assertNull("Name must not have a genus eptithet", name1.getGenusOrUninomial());
578
        assertNull("Name must not have a specific eptithet", name1.getSpecificEpithet());
579
        assertFalse("Name must not have parsing problems", name1.hasProblem());
580

    
581
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
582
        assertFalse("Name must not have parsing problems", name1.hasProblem());
583

    
584
        //x-sign
585
        hybridCache = "Abies alba x Pinus bus";
586
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
587
        assertFalse("Name must be parsable", name1.hasProblem());
588
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
589
        assertFalse("Name must not have parsing problems", name1.hasProblem());
590

    
591
        //Genus //#6030
592
        hybridCache = "Orchis "+UTF8.HYBRID+" Platanthera";
593
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
594
        assertFalse("Name must be parsable", name1.hasProblem());
595
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
596
        assertFalse("Name must not have parsing problems", name1.hasProblem());
597
        assertEquals("Title cache must be correct", hybridCache, name1.getTitleCache());
598
        orderedRels = name1.getOrderedChildRelationships();
599
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
600
        firstParent = orderedRels.get(0).getParentName();
601
        assertEquals("Name must have Orchis as first hybrid parent", "Orchis", firstParent.getTitleCache());
602
        secondParent = orderedRels.get(1).getParentName();
603
        assertEquals("Name must have Platanthera as second hybrid parent", "Platanthera", secondParent.getTitleCache());
604
        assertEquals("Hybrid name must have genus as rank", Rank.GENUS(), name1.getRank());
605

    
606
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
607
        assertFalse("Name must not have parsing problems", name1.hasProblem());
608

    
609
        //Subspecies first hybrid
610
        name1 = parser.parseFullName("Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", botanicCode, null);
611
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
612
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
613
        assertEquals("Title cache must be correct", "Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", name1.getTitleCache());
614
        orderedRels = name1.getOrderedChildRelationships();
615
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
616
        firstParent = orderedRels.get(0).getParentName();
617
        assertEquals("Name must have Abies alba subsp. beta as first hybrid parent", "Abies alba subsp. beta", firstParent.getTitleCache());
618
        secondParent = orderedRels.get(1).getParentName();
619
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
620
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
621

    
622
        //variety second hybrid
623
        name1 = parser.parseFullName("Abies alba \u00D7 Pinus bus  var. beta", botanicCode, null);
624
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
625
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
626
        assertEquals("Title cache must be correct", "Abies alba \u00D7 Pinus bus var. beta", name1.getTitleCache());
627
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
628

    
629
        //hybrids with authors  //happens but questionable
630
        name1 = parser.parseFullName("Abies alba L. \u00D7 Pinus bus Mill.", botanicCode, null);
631
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
632
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
633
        assertEquals("Title cache must be correct", "Abies alba L. \u00D7 Pinus bus Mill.", name1.getTitleCache());
634
        orderedRels = name1.getOrderedChildRelationships();
635
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
636
        firstParent = orderedRels.get(0).getParentName();
637
        assertEquals("Name must have Abies alba L. as first hybrid parent", "Abies alba L.", firstParent.getTitleCache());
638
        secondParent = orderedRels.get(1).getParentName();
639
        assertEquals("Name must have Pinus bus Mill. as second hybrid parent", "Pinus bus Mill.", secondParent.getTitleCache());
640
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
641

    
642
        //abbreviated genus hybrid formula #6410 / #5983
643
        String nameStr = "Nepenthes mirabilis \u00D7 N. alata";
644
        name1 = parser.parseFullName(nameStr, botanicCode, null);
645
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
646
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
647
        //could also be N. or no genus at all, depends on formatter
648
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
649
        orderedRels = name1.getOrderedChildRelationships();
650
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
651
        firstParent = orderedRels.get(0).getParentName();
652
        //to be discussed as usually they should be ordered alphabetically
653
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
654
        secondParent = orderedRels.get(1).getParentName();
655
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
656
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
657

    
658
        //missing genus hybrid formula #5983
659
        nameStr = "Nepenthes mirabilis \u00D7 alata";
660
        name1 = parser.parseFullName(nameStr, botanicCode, null);
661
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
662
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
663
        //could also be N. or no genus at all, depends on formatter
664
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
665
        orderedRels = name1.getOrderedChildRelationships();
666
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
667
        firstParent = orderedRels.get(0).getParentName();
668
        //to be discussed as usually they should be ordered alphabetically
669
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
670
        secondParent = orderedRels.get(1).getParentName();
671
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
672
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
673

    
674
        //#5983 subsp. with species and missing genus
675
        nameStr = "Orchis coriophora subsp. fragrans \u00D7 sancta";
676
        name1 = parser.parseFullName(nameStr, botanicCode, null);
677
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
678
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
679
        //could also be N. or no genus at all, depends on formatter
680
        assertEquals("Title cache must be correct", "Orchis coriophora subsp. fragrans \u00D7 Orchis sancta", name1.getTitleCache());
681
        orderedRels = name1.getOrderedChildRelationships();
682
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
683
        firstParent = orderedRels.get(0).getParentName();
684
        assertEquals("Name must have Orchis coriophora subsp. fragrans as first hybrid parent", "Orchis coriophora subsp. fragrans", firstParent.getTitleCache());
685
        secondParent = orderedRels.get(1).getParentName();
686
        assertEquals("Name must have Orchis sancta as second hybrid parent", "Orchis sancta", secondParent.getTitleCache());
687
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
688

    
689
        //2 subspecies with missing genus part #5983
690
        nameStr = "Orchis morio subsp. syriaca \u00D7 papilionacea subsp. schirvanica";
691
        name1 = parser.parseFullName(nameStr, botanicCode, null);
692
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
693
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
694
        //could also be N. or no genus at all, depends on formatter
695
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis papilionacea subsp. schirvanica", name1.getTitleCache());
696
        orderedRels = name1.getOrderedChildRelationships();
697
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
698
        firstParent = orderedRels.get(0).getParentName();
699
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
700
        secondParent = orderedRels.get(1).getParentName();
701
        assertEquals("Name must have Orchis papilionacea subsp. schirvanica as second hybrid parent", "Orchis papilionacea subsp. schirvanica", secondParent.getTitleCache());
702
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
703

    
704
        //subspecies and variety with missing genus part
705
        nameStr = "Orchis morio subsp. syriaca \u00D7 papilionacea var. schirvanica";
706
        name1 = parser.parseFullName(nameStr, botanicCode, null);
707
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
708
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
709
        //could also be N. or no genus at all, depends on formatter
710
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis papilionacea var. schirvanica", name1.getTitleCache());
711
        orderedRels = name1.getOrderedChildRelationships();
712
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
713
        firstParent = orderedRels.get(0).getParentName();
714
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
715
        secondParent = orderedRels.get(1).getParentName();
716
        assertEquals("Name must have Orchis papilionacea var. schirvanica as second hybrid parent", "Orchis papilionacea var. schirvanica", secondParent.getTitleCache());
717
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
718

    
719
        //subspecies and variety with genus part
720
        nameStr = "Orchis morio subsp. syriaca \u00D7 Test papilionacea var. schirvanica";
721
        name1 = parser.parseFullName(nameStr, botanicCode, null);
722
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
723
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
724
        //could also be N. or no genus at all, depends on formatter
725
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Test papilionacea var. schirvanica", name1.getTitleCache());
726
        orderedRels = name1.getOrderedChildRelationships();
727
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
728
        firstParent = orderedRels.get(0).getParentName();
729
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
730
        secondParent = orderedRels.get(1).getParentName();
731
        assertEquals("Name must have Orchis papilionacea var. schirvanica as second hybrid parent", "Test papilionacea var. schirvanica", secondParent.getTitleCache());
732
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
733

    
734
        //2 subspecies with missing genus and species part #5983
735
        nameStr = "Orchis morio subsp. syriaca \u00D7 subsp. schirvanica";
736
        name1 = parser.parseFullName(nameStr, botanicCode, null);
737
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
738
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
739
        //could also be N. or no genus at all, depends on formatter
740
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio subsp. schirvanica", name1.getTitleCache());
741
        orderedRels = name1.getOrderedChildRelationships();
742
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
743
        firstParent = orderedRels.get(0).getParentName();
744
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
745
        secondParent = orderedRels.get(1).getParentName();
746
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio subsp. schirvanica", secondParent.getTitleCache());
747
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
748

    
749
        //subspecies and variety with missing genus and species part #5983
750
        nameStr = "Orchis morio subsp. syriaca \u00D7 var. schirvanica";
751
        name1 = parser.parseFullName(nameStr, botanicCode, null);
752
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
753
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
754
        //could also be N. or no genus at all, depends on formatter
755
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio var. schirvanica", name1.getTitleCache());
756
        orderedRels = name1.getOrderedChildRelationships();
757
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
758
        firstParent = orderedRels.get(0).getParentName();
759
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
760
        secondParent = orderedRels.get(1).getParentName();
761
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio var. schirvanica", secondParent.getTitleCache());
762
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
763
    }
764

    
765
    @Test
766
    public final void testUninomials() {
767
        String uninomial = "Anserineae";  //this, in reality is a tribe but the parser should recognize a suborder as the suborder ending -ineae is more specific then the tribe ending -eae
768
        INonViralName name = parser.parseFullName(uninomial, botanicCode, null);
769
        assertEquals(Rank.SUBORDER(), name.getRank());
770
    }
771

    
772
    @Test
773
    public final void testUnrankedNames() {
774
        try {
775
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
776
            testName_StringNomcodeRank(parseMethod);
777
        } catch (Exception e) {
778
            e.printStackTrace();
779
            assertTrue(false);
780
        }
781

    
782
        //unranked infraspecific
783
        String infraspecificUnranked = "Genus species [unranked] infraspecific";
784
        INonViralName name = parser.parseFullName(infraspecificUnranked);
785
        assertEquals( "Genus", name.getGenusOrUninomial());
786
        assertEquals( "species", name.getSpecificEpithet());
787
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
788
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
789

    
790
        //'ranglos' infraspecific
791
        infraspecificUnranked = "Genus species [ranglos] infraspecific";
792
        name = parser.parseFullName(infraspecificUnranked);
793
        assertEquals( "Genus", name.getGenusOrUninomial());
794
        assertEquals( "species", name.getSpecificEpithet());
795
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
796
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
797

    
798
        //unranked infrageneric
799
        String infraGenericUnranked = "Genus [unranked] Infragen";
800
        INonViralName name2 = parser.parseFullName(infraGenericUnranked);
801
        assertEquals( "Genus", name2.getGenusOrUninomial());
802
        assertEquals( null, name2.getSpecificEpithet());
803
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
804
        assertEquals( "Unranked rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
805

    
806
        //unranked infrageneric
807
        infraGenericUnranked = "Genus [ranglos] Infragen";
808
         name2 = parser.parseFullName(infraGenericUnranked);
809
        assertEquals( "Genus", name2.getGenusOrUninomial());
810
        assertEquals( null, name2.getSpecificEpithet());
811
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
812
        assertEquals( "Ranglos rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
813

    
814
    }
815

    
816
    @Test
817
    public final void testOldRanks() {
818
        try {
819
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
820
            testName_StringNomcodeRank(parseMethod);
821
        } catch (Exception e) {
822
            e.printStackTrace();
823
            assertTrue(false);
824
        }
825

    
826
        //proles
827
        String infraspecificUnranked = "Genus species proles infraspecific";
828
        INonViralName name = parser.parseFullName(infraspecificUnranked);
829
        assertEquals( "Genus", name.getGenusOrUninomial());
830
        assertEquals( "species", name.getSpecificEpithet());
831
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
832
        assertEquals( "Proles should be parsed", Rank.PROLES(), name.getRank());
833

    
834
        //subproles
835
        infraspecificUnranked = "Genus species subproles infraspecific";
836
        name = parser.parseFullName(infraspecificUnranked);
837
        assertEquals( "Genus", name.getGenusOrUninomial());
838
        assertEquals( "species", name.getSpecificEpithet());
839
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
840
        assertEquals( "Subproles should be parsed", Rank.SUBPROLES(), name.getRank());
841

    
842
        //prol.
843
        infraspecificUnranked = "Genus species prol. infraspecific";
844
        name = parser.parseFullName(infraspecificUnranked);
845
        assertEquals( "Genus", name.getGenusOrUninomial());
846
        assertEquals( "species", name.getSpecificEpithet());
847
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
848
        assertEquals( "Prol. should be parsed", Rank.PROLES(), name.getRank());
849

    
850
        //subproles
851
        infraspecificUnranked = "Genus species subprol. infraspecific";
852
        name = parser.parseFullName(infraspecificUnranked);
853
        assertEquals( "Genus", name.getGenusOrUninomial());
854
        assertEquals( "species", name.getSpecificEpithet());
855
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
856
        assertEquals( "Subprol. should be parsed", Rank.SUBPROLES(), name.getRank());
857

    
858
        //lusus
859
        infraspecificUnranked = "Genus species lusus infraspecific";
860
        name = parser.parseFullName(infraspecificUnranked);
861
        assertEquals( "Genus", name.getGenusOrUninomial());
862
        assertEquals( "species", name.getSpecificEpithet());
863
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
864
        assertEquals( "Sublusus should be parsed", Rank.LUSUS(), name.getRank());
865

    
866
        //sublusus
867
        infraspecificUnranked = "Genus species sublusus infraspecific";
868
        name = parser.parseFullName(infraspecificUnranked);
869
        assertEquals( "Genus", name.getGenusOrUninomial());
870
        assertEquals( "species", name.getSpecificEpithet());
871
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
872
        assertEquals( "Sublusus should be parsed", Rank.SUBLUSUS(), name.getRank());
873

    
874
        //race
875
        infraspecificUnranked = "Genus species race infraspecific";
876
        name = parser.parseFullName(infraspecificUnranked);
877
        assertEquals( "Genus", name.getGenusOrUninomial());
878
        assertEquals( "species", name.getSpecificEpithet());
879
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
880
        assertEquals( "Race should be parsed", Rank.RACE(), name.getRank());
881

    
882
        //grex
883
        infraspecificUnranked = "Genus species grex infraspecific";
884
        name = parser.parseFullName(infraspecificUnranked);
885
        assertEquals( "Genus", name.getGenusOrUninomial());
886
        assertEquals( "species", name.getSpecificEpithet());
887
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
888
        assertEquals( "Grex should be parsed", Rank.GREX_INFRASPEC(), name.getRank());
889

    
890
        //subgrex
891
        infraspecificUnranked = "Genus species subgrex infraspecific";
892
        name = parser.parseFullName(infraspecificUnranked);
893
        assertEquals( "Genus", name.getGenusOrUninomial());
894
        assertEquals( "species", name.getSpecificEpithet());
895
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
896
        assertEquals( "Subgrex should be parsed", Rank.SUBGREX(), name.getRank());
897
    }
898

    
899
    @Test
900
    public final void testTemp(){
901

    
902
//        String nameStr = "Mentha aquatica L. x Mentha spicata L.";
903
//        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
904
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
905
//        assertFalse( name.getHybridChildRelations().isEmpty());
906
//        for (HybridRelationship rel : name.getHybridChildRelations()){
907
//            TaxonName parent = rel.getParentName();
908
//            System.out.println(parent.getTitleCache());
909
//        }
910
    }
911

    
912
    @Test
913
    public final void testHybridsRemoval(){
914
        //if the parser input already has hybridrelationships they need to be removed
915
        //Create input
916
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
917
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
918
        assertFalse("Name must not have parsing problems", name1.hasProblem());
919
        assertTrue("", name1.getHybridChildRelations().size() == 2);
920

    
921
        hybridCache = "Abieta albana "+UTF8.HYBRID+" Pinuta custa";
922
        boolean makeEmpty = true;
923
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
924
        assertEquals("After parsing another string there should still be 2 parents, but different ones", 2, name1.getHybridChildRelations().size());
925
        assertFalse("Name must not have parsing problems", name1.hasProblem());
926

    
927

    
928
        hybridCache = "Calendula arvensis Mill.";
929
        makeEmpty = true;
930
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
931
        assertTrue("", name1.getHybridChildRelations().isEmpty());
932
        assertFalse("Name must not have parsing problems", name1.hasProblem());
933

    
934

    
935
        //AND the same for reference parsing
936
        hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
937
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
938
        assertFalse("Name must not have parsing problems", name1.hasProblem());
939
        assertTrue("", name1.getHybridChildRelations().size() == 2);
940

    
941
        hybridCache = "Abieta albana "+UTF8.HYBRID+" Pinuta custa";
942
        makeEmpty = true;
943
        parser.parseReferencedName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
944
        assertEquals("After parsing another string there should still be 2 parents, but different ones", 2, name1.getHybridChildRelations().size());
945
        assertFalse("Name must not have parsing problems", name1.hasProblem());
946

    
947
        hybridCache = "Calendula arvensis Mill.";
948
        makeEmpty = true;
949
        parser.parseReferencedName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
950
        assertTrue("", name1.getHybridChildRelations().isEmpty());
951
        assertFalse("Name must not have parsing problems", name1.hasProblem());
952
    }
953

    
954
    private void testName_StringNomcodeRank(Method parseMethod)
955
            throws InvocationTargetException, IllegalAccessException  {
956
        INonViralName name1 = (INonViralName)parseMethod.invoke(parser, strNameAbies1, null, Rank.SPECIES());
957
        //parser.parseFullName(strNameAbies1, null, Rank.SPECIES());
958
        assertEquals("Abies", name1.getGenusOrUninomial());
959
        assertEquals("alba", name1.getSpecificEpithet());
960

    
961
        INonViralName nameAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesAuthor1, null, Rank.SPECIES());
962
        assertEquals("Abies", nameAuthor.getGenusOrUninomial());
963
        assertEquals("alba", nameAuthor.getSpecificEpithet());
964
        assertEquals("Mueller", nameAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
965

    
966
        INonViralName nameBasionymAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymAuthor1, null, Rank.SPECIES());
967
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
968
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
969
        assertEquals("D'Mueller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
970
        assertEquals("Ciardelli", nameBasionymAuthor.getBasionymAuthorship().getNomenclaturalTitleCache());
971

    
972
        INonViralName nameBasionymExAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymExAuthor1, null, Rank.SPECIES());
973
        assertEquals("Abies", nameBasionymExAuthor.getGenusOrUninomial());
974
        assertEquals("alba", nameBasionymExAuthor.getSpecificEpithet());
975
        assertEquals("D'Mueller", nameBasionymExAuthor.getExCombinationAuthorship().getNomenclaturalTitleCache());
976
        assertEquals("de Greuther", nameBasionymExAuthor.getCombinationAuthorship().getNomenclaturalTitleCache());
977
        assertEquals("Ciardelli", nameBasionymExAuthor.getExBasionymAuthorship().getNomenclaturalTitleCache());
978
        assertEquals("Doering", nameBasionymExAuthor.getBasionymAuthorship().getNomenclaturalTitleCache());
979

    
980
        INonViralName name2 = (INonViralName)parseMethod.invoke(parser, strNameAbiesSub1, null, Rank.SPECIES());
981
        assertEquals("Abies", name2.getGenusOrUninomial());
982
        assertEquals("alba", name2.getSpecificEpithet());
983
        assertEquals("beta", name2.getInfraSpecificEpithet());
984
        assertEquals(Rank.SUBSPECIES(), name2.getRank());
985

    
986

    
987
        // unparseable *********
988
        String problemString = "sdfjlös wer eer wer";
989
        INonViralName nameProblem = (INonViralName)parseMethod.invoke(parser, problemString, null, Rank.SPECIES());
990
        List<ParserProblem> list = nameProblem.getParsingProblems();
991
        assertTrue(nameProblem.getParsingProblem()!=0);
992
        assertEquals(problemString, nameProblem.getTitleCache());
993
    }
994

    
995

    
996
    /**
997
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
998
     */
999
    @Test
1000
    public final void testParseNomStatus() {
1001
        //nom. ambig.
1002
        String strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. ambig.";
1003
        INonViralName nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1004
        assertFullRefStandard(nameTestStatus);
1005
        assertTrue(nameTestStatus.getStatus().size()== 1);
1006
        assertEquals( NomenclaturalStatusType.AMBIGUOUS(), nameTestStatus.getStatus().iterator().next().getType());
1007

    
1008
        //nom. inval.
1009
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. inval.";
1010
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1011
        assertFullRefStandard(nameTestStatus);
1012
        assertTrue(nameTestStatus.getStatus().size()== 1);
1013
        assertEquals( NomenclaturalStatusType.INVALID(), nameTestStatus.getStatus().iterator().next().getType());
1014

    
1015
        //nom. dub.
1016
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. dub.";
1017
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1018
        assertFullRefStandard(nameTestStatus);
1019
        assertTrue(nameTestStatus.getStatus().size()== 1);
1020
        assertEquals( NomenclaturalStatusType.DOUBTFUL(), nameTestStatus.getStatus().iterator().next().getType());
1021

    
1022
        //nom. confus.
1023
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. confus.";
1024
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1025
        assertFullRefStandard(nameTestStatus);
1026
        assertTrue(nameTestStatus.getStatus().size()== 1);
1027
        assertEquals( NomenclaturalStatusType.CONFUSUM(), nameTestStatus.getStatus().iterator().next().getType());
1028

    
1029
        //nom. illeg.
1030
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. illeg.";
1031
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1032
        assertFullRefStandard(nameTestStatus);
1033
        assertTrue(nameTestStatus.getStatus().size()== 1);
1034
        assertEquals( NomenclaturalStatusType.ILLEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
1035

    
1036
        //nom. superfl.
1037
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. superfl.";
1038
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1039
        assertFullRefStandard(nameTestStatus);
1040
        assertTrue(nameTestStatus.getStatus().size()== 1);
1041
        assertEquals( NomenclaturalStatusType.SUPERFLUOUS(), nameTestStatus.getStatus().iterator().next().getType());
1042

    
1043
        //nom. rej.
1044
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. rej.";
1045
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1046
        assertFullRefStandard(nameTestStatus);
1047
        assertTrue(nameTestStatus.getStatus().size()== 1);
1048
        assertEquals( NomenclaturalStatusType.REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1049

    
1050
        //nom. utique rej.
1051
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. utique rej.";
1052
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1053
        assertFullRefStandard(nameTestStatus);
1054
        assertTrue(nameTestStatus.getStatus().size()== 1);
1055
        assertEquals( NomenclaturalStatusType.UTIQUE_REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1056

    
1057
        //nom. cons. prop.
1058
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons. prop.";
1059
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1060
        assertFullRefStandard(nameTestStatus);
1061
        assertTrue(nameTestStatus.getStatus().size()== 1);
1062
        assertEquals( NomenclaturalStatusType.CONSERVED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1063

    
1064
        //nom. orth. cons. prop.
1065
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, orth. cons. prop.";
1066
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1067
        assertFullRefStandard(nameTestStatus);
1068
        assertTrue(nameTestStatus.getStatus().size()== 1);
1069
        assertEquals( NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1070

    
1071
        //nom. cons. prop.
1072
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons. des.";
1073
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1074
        assertFullRefStandard(nameTestStatus);
1075
        assertTrue(nameTestStatus.getStatus().size()== 1);
1076
        assertEquals( NomenclaturalStatusType.CONSERVED_DESIG(), nameTestStatus.getStatus().iterator().next().getType());
1077

    
1078
        //nom. legit.
1079
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. legit.";
1080
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1081
        assertFullRefStandard(nameTestStatus);
1082
        assertTrue(nameTestStatus.getStatus().size()== 1);
1083
        assertEquals( NomenclaturalStatusType.LEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
1084

    
1085
        //nom. altern.
1086
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. altern.";
1087
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1088
        assertFullRefStandard(nameTestStatus);
1089
        assertTrue(nameTestStatus.getStatus().size()== 1);
1090
        assertEquals( NomenclaturalStatusType.ALTERNATIVE(), nameTestStatus.getStatus().iterator().next().getType());
1091

    
1092
        //nom. alternativ.
1093
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. alternativ.";
1094
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1095
        assertFullRefStandard(nameTestStatus);
1096
        assertTrue(nameTestStatus.getStatus().size()== 1);
1097
        assertEquals( NomenclaturalStatusType.ALTERNATIVE(), nameTestStatus.getStatus().iterator().next().getType());
1098

    
1099
        //nom. nov.
1100
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. nov.";
1101
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1102
        assertFullRefStandard(nameTestStatus);
1103
        assertTrue(nameTestStatus.getStatus().size()== 1);
1104
        assertEquals( NomenclaturalStatusType.NOVUM(), nameTestStatus.getStatus().iterator().next().getType());
1105

    
1106
        //nom. utique rej. prop.
1107
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. utique rej. prop.";
1108
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1109
        assertFullRefStandard(nameTestStatus);
1110
        assertTrue(nameTestStatus.getStatus().size()== 1);
1111
        assertEquals( NomenclaturalStatusType.UTIQUE_REJECTED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1112

    
1113
        //nom. orth. cons.
1114
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, orth. cons.";
1115
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1116
        assertFullRefStandard(nameTestStatus);
1117
        assertTrue(nameTestStatus.getStatus().size()== 1);
1118
        assertEquals( NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED(), nameTestStatus.getStatus().iterator().next().getType());
1119

    
1120
        //nom. rej. prop.
1121
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. rej. prop.";
1122
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1123
        assertFullRefStandard(nameTestStatus);
1124
        assertTrue(nameTestStatus.getStatus().size()== 1);
1125
        assertEquals( NomenclaturalStatusType.REJECTED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1126

    
1127
        //nom. cons.
1128
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons.";
1129
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1130
        assertFullRefStandard(nameTestStatus);
1131
        assertTrue(nameTestStatus.getStatus().size()== 1);
1132
        assertEquals( NomenclaturalStatusType.CONSERVED(), nameTestStatus.getStatus().iterator().next().getType());
1133

    
1134
        //nom. sanct.
1135
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. sanct.";
1136
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1137
        assertFullRefStandard(nameTestStatus);
1138
        assertTrue(nameTestStatus.getStatus().size()== 1);
1139
        assertEquals( NomenclaturalStatusType.SANCTIONED(), nameTestStatus.getStatus().iterator().next().getType());
1140

    
1141
        //nom. nud.
1142
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. nud.";
1143
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1144
        assertFullRefStandard(nameTestStatus);
1145
        assertTrue(nameTestStatus.getStatus().size()== 1);
1146
        assertEquals( NomenclaturalStatusType.NUDUM(), nameTestStatus.getStatus().iterator().next().getType());
1147

    
1148
        //comb. inval.
1149
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. inval.";
1150
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1151
        assertFullRefStandard(nameTestStatus);
1152
        assertTrue(nameTestStatus.getStatus().size()== 1);
1153
        assertEquals( NomenclaturalStatusType.COMBINATION_INVALID(), nameTestStatus.getStatus().iterator().next().getType());
1154

    
1155
        //comb. illeg.
1156
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. illeg.";
1157
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1158
        assertFullRefStandard(nameTestStatus);
1159
        assertTrue(nameTestStatus.getStatus().size()== 1);
1160
        assertEquals( NomenclaturalStatusType.COMBINATION_ILLEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
1161

    
1162
        //nom. provis.
1163
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. provis.";
1164
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1165
        assertFullRefStandard(nameTestStatus);
1166
        assertTrue(nameTestStatus.getStatus().size()== 1);
1167
        assertEquals( NomenclaturalStatusType.PROVISIONAL(), nameTestStatus.getStatus().iterator().next().getType());
1168

    
1169
        //nom. val.
1170
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. val.";
1171
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1172
        assertFullRefStandard(nameTestStatus);
1173
        assertTrue(nameTestStatus.getStatus().size()== 1);
1174
        assertEquals( NomenclaturalStatusType.VALID(), nameTestStatus.getStatus().iterator().next().getType());
1175

    
1176
        //nom. subnud.
1177
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. subnud.";
1178
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1179
        assertFullRefStandard(nameTestStatus);
1180
        assertTrue(nameTestStatus.getStatus().size()== 1);
1181
        assertEquals( NomenclaturalStatusType.SUBNUDUM(), nameTestStatus.getStatus().iterator().next().getType());
1182

    
1183
        //opus. utique oppr.
1184
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, op. utique oppr.";
1185
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1186
        assertFullRefStandard(nameTestStatus);
1187
        assertTrue(nameTestStatus.getStatus().size()== 1);
1188
        assertEquals( NomenclaturalStatusType.OPUS_UTIQUE_OPPR(), nameTestStatus.getStatus().iterator().next().getType());
1189

    
1190
        //comb. nov.
1191
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. nov.";
1192
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1193
        assertFullRefStandard(nameTestStatus);
1194
        assertTrue(nameTestStatus.getStatus().size()== 1);
1195
        assertEquals( NomenclaturalStatusType.COMB_NOV(), nameTestStatus.getStatus().iterator().next().getType());
1196

    
1197
        //orth. rej.
1198
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, orth. rej.";
1199
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1200
        assertFullRefStandard(nameTestStatus);
1201
        assertTrue(nameTestStatus.getStatus().size()== 1);
1202
        assertEquals( NomenclaturalStatusType.ORTHOGRAPHY_REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1203

    
1204
        //ined.
1205
        strTestStatus = "Houstonia macvaughii (Terrell), ined.";
1206
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1207
        assertEquals("Houstonia", nameTestStatus.getGenusOrUninomial());
1208
        assertEquals("macvaughii", nameTestStatus.getSpecificEpithet());
1209
        assertEquals("(Terrell)", nameTestStatus.getAuthorshipCache());
1210
        assertEquals(1, nameTestStatus.getStatus().size());
1211
        assertEquals( NomenclaturalStatusType.INED(), nameTestStatus.getStatus().iterator().next().getType());
1212

    
1213
        //not yet parsed "not avail."
1214
    }
1215

    
1216
    /**
1217
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
1218
     */
1219
    @Test
1220
    public final void testParseReferencedName() {
1221
        try {
1222
            Method parseMethod = parser.getClass().getDeclaredMethod("parseReferencedName", String.class, NomenclaturalCode.class, Rank.class);
1223
            testName_StringNomcodeRank(parseMethod);
1224
        } catch (Exception e) {
1225
            e.printStackTrace();
1226
            assertTrue(false);
1227
        }
1228

    
1229
        //null
1230
        String strNull = null;
1231
        Rank rankSpecies = Rank.SPECIES();
1232
        INonViralName nameNull = parser.parseReferencedName(strNull, null, rankSpecies);
1233
        assertNull(nameNull);
1234

    
1235
        //Empty
1236
        String strEmpty = "";
1237
        INonViralName nameEmpty = parser.parseReferencedName(strEmpty, null, rankSpecies);
1238
        assertFalse(nameEmpty.hasProblem());
1239
        assertEquals(strEmpty, nameEmpty.getFullTitleCache());
1240
        assertNull(nameEmpty.getNomenclaturalMicroReference());
1241

    
1242
        //Whitespaces
1243
        String strFullWhiteSpcaceAndDot = "Abies alba Mill.,  Sp.   Pl.  4:  455 .  1987 .";
1244
        INonViralName namefullWhiteSpcaceAndDot = parser.parseReferencedName(strFullWhiteSpcaceAndDot, null, rankSpecies);
1245
        assertFullRefStandard(namefullWhiteSpcaceAndDot);
1246
        assertTrue(namefullWhiteSpcaceAndDot.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1247
        assertEquals( "Abies alba Mill., Sp. Pl. 4: 455. 1987", namefullWhiteSpcaceAndDot.getFullTitleCache());
1248

    
1249
        //Book
1250
        String fullReference = "Abies alba Mill., Sp. Pl. 4: 455. 1987";
1251
        INonViralName name1 = parser.parseReferencedName(fullReference, null, rankSpecies);
1252
        assertFullRefStandard(name1);
1253
        assertTrue(name1.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1254
        assertEquals(fullReference, name1.getFullTitleCache());
1255
        assertTrue("Name author and reference author should be the same", name1.getCombinationAuthorship() == name1.getNomenclaturalReference().getAuthorship());
1256

    
1257
        //Book Section
1258
        fullReference = "Abies alba Mill. in Otto, Sp. Pl. 4(6): 455. 1987";
1259
        INonViralName name2 = parser.parseReferencedName(fullReference + ".", null, rankSpecies);
1260
        assertFullRefNameStandard(name2);
1261
        assertEquals(fullReference, name2.getFullTitleCache());
1262
        assertFalse(name2.hasProblem());
1263
        INomenclaturalReference ref = name2.getNomenclaturalReference();
1264
        assertEquals(ReferenceType.BookSection, ((Reference)ref).getType());
1265
        IBookSection bookSection = (IBookSection) ref;
1266
        IBook inBook = bookSection.getInBook();
1267
        assertNotNull(inBook);
1268
        assertNotNull(inBook.getAuthorship());
1269
        assertEquals("Otto", inBook.getAuthorship().getTitleCache());
1270
        assertEquals("Otto: Sp. Pl. 4(6)", inBook.getTitleCache());
1271
        assertEquals("Sp. Pl.", inBook.getAbbrevTitle());
1272
        assertEquals("4(6)", inBook.getVolume());
1273
        assertTrue("Name author and reference author should be the same", name2.getCombinationAuthorship() == name2.getNomenclaturalReference().getAuthorship());
1274

    
1275
        //Article
1276
        fullReference = "Abies alba Mill. in Sp. Pl. 4(6): 455. 1987";
1277
        INonViralName name3 = parser.parseReferencedName(fullReference, null, rankSpecies);
1278
        assertFullRefNameStandard(name3);
1279
        name3.setTitleCache(null);
1280
        assertEquals(fullReference, name3.getFullTitleCache());
1281
        assertFalse(name3.hasProblem());
1282
        ref = name3.getNomenclaturalReference();
1283
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1284
        //Article article = (Article)ref;
1285
        IJournal journal = ((IArticle)ref).getInJournal();
1286
        assertNotNull(journal);
1287
        //assertEquals("Sp. Pl. 4(6)", inBook.getTitleCache());
1288
        assertEquals("Sp. Pl.",((Reference) journal).getTitleCache());
1289
        assertEquals("Sp. Pl.", journal.getAbbrevTitle());
1290
        assertEquals("4(6)",((IArticle)ref).getVolume());
1291
        assertTrue("Name author and reference author should be the same", name3.getCombinationAuthorship() == name3.getNomenclaturalReference().getAuthorship());
1292

    
1293
        //Article with volume range
1294
        fullReference = "Abies alba Mill. in Sp. Pl. 4(1-2): 455. 1987";
1295
        INonViralName name3a = parser.parseReferencedName(fullReference, null, rankSpecies);
1296
        name3a.setTitleCache(null);
1297
        assertEquals(fullReference, name3a.getFullTitleCache());
1298
        assertFalse(name3a.hasProblem());
1299
        ref = name3a.getNomenclaturalReference();
1300
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1301
        assertEquals("4(1-2)",((IArticle)ref).getVolume());
1302

    
1303
        //SoftArticle - having "," on position > 4
1304
        String journalTitle = "Bull. Soc. Bot.France. Louis., Roi";
1305
        String yearPart = " 1987 - 1989";
1306
        String parsedYearFormatted = "1987"+SEP+"1989";
1307
        String fullReferenceWithoutYear = "Abies alba Mill. in " + journalTitle + " 4(6): 455.";
1308
        fullReference = fullReferenceWithoutYear + yearPart;
1309
        String fullReferenceWithEnd = fullReference + ".";
1310
        INonViralName name4 = parser.parseReferencedName(fullReferenceWithEnd, null, rankSpecies);
1311
        assertFalse(name4.hasProblem());
1312
        assertFullRefNameStandard(name4);
1313
        assertEquals(fullReferenceWithoutYear + " " + parsedYearFormatted, name4.getFullTitleCache());
1314
        ref = name4.getNomenclaturalReference();
1315
        assertEquals(ReferenceType.Article, ref.getType());
1316
        //article = (Article)ref;
1317
        assertEquals(parsedYearFormatted, ref.getYear());
1318
        journal = ((IArticle)ref).getInJournal();
1319
        assertNotNull(journal);
1320
        assertEquals(journalTitle, ((Reference) journal).getTitleCache());
1321
        assertEquals(journalTitle, journal.getAbbrevTitle());
1322
        assertEquals("4(6)", ((IArticle)ref).getVolume());
1323

    
1324
        //Zoo name
1325
        String strNotParsableZoo = "Abies alba M., 1923, Sp. P. xxwer4352, nom. inval.";
1326
        IZoologicalName nameZooRefNotParsabel = parser.parseReferencedName(strNotParsableZoo, null, null);
1327
        assertTrue(nameZooRefNotParsabel.hasProblem());
1328
        List<ParserProblem> list = nameZooRefNotParsabel.getParsingProblems();
1329
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1330
        assertEquals(21, nameZooRefNotParsabel.getProblemStarts());
1331
        assertEquals(37, nameZooRefNotParsabel.getProblemEnds());
1332
        assertTrue(nameZooRefNotParsabel.getNomenclaturalReference().hasProblem());
1333
        list = nameZooRefNotParsabel.getNomenclaturalReference().getParsingProblems();
1334
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1335

    
1336
        assertEquals(NomenclaturalCode.ICZN, nameZooRefNotParsabel.getNameType());
1337
        assertEquals(Integer.valueOf(1923), nameZooRefNotParsabel.getPublicationYear());
1338
        assertEquals(1, nameZooRefNotParsabel.getStatus().size());
1339

    
1340
        String strZooNameSineYear = "Homo sapiens L., 1758, Sp. An. 3: 345";
1341
        IZoologicalName nameZooNameSineYear = parser.parseReferencedName(strZooNameSineYear);
1342
        assertFalse(nameZooNameSineYear.hasProblem());
1343
        assertEquals("Name without reference year must have year", (Integer)1758, nameZooNameSineYear.getPublicationYear());
1344
        assertEquals("Name without reference year must have year", "1758", nameZooNameSineYear.getNomenclaturalReference().getYear());
1345

    
1346
        String strZooNameNewCombination = "Homo sapiens (L., 1758) Mill., 1830, Sp. An. 3: 345";
1347
        IZoologicalName nameZooNameNewCombination = parser.parseReferencedName(strZooNameNewCombination);
1348
        assertTrue(nameZooNameNewCombination.hasProblem());
1349
        list = nameZooNameNewCombination.getParsingProblems();
1350
        assertTrue("List must contain new combination has publication warning ", list.contains(ParserProblem.NewCombinationHasPublication));
1351
        assertEquals(35, nameZooNameNewCombination.getProblemStarts());
1352
        assertEquals(51, nameZooNameNewCombination.getProblemEnds());
1353

    
1354
        //Special MicroRefs
1355
        String strSpecDetail1 = "Abies alba Mill. in Sp. Pl. 4(6): [455]. 1987";
1356
        INonViralName nameSpecDet1 = parser.parseReferencedName(strSpecDetail1 + ".", null, rankSpecies);
1357
        assertFalse(nameSpecDet1.hasProblem());
1358
        assertEquals(strSpecDetail1, nameSpecDet1.getFullTitleCache());
1359
        assertEquals("[455]", nameSpecDet1.getNomenclaturalMicroReference());
1360

    
1361
        //Special MicroRefs
1362
        String strSpecDetail2 = "Abies alba Mill. in Sp. Pl. 4(6): couv. 2. 1987";
1363
        INonViralName nameSpecDet2 = parser.parseReferencedName(strSpecDetail2 + ".", null, rankSpecies);
1364
        assertFalse(nameSpecDet2.hasProblem());
1365
        assertEquals(strSpecDetail2, nameSpecDet2.getFullTitleCache());
1366
        assertEquals("couv. 2", nameSpecDet2.getNomenclaturalMicroReference());
1367

    
1368
        //Special MicroRefs
1369
        String strSpecDetail3 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455. 1987";
1370
        INonViralName nameSpecDet3 = parser.parseReferencedName(strSpecDetail3 + ".", null, rankSpecies);
1371
        assertFalse(nameSpecDet3.hasProblem());
1372
        assertEquals(strSpecDetail3, nameSpecDet3.getFullTitleCache());
1373
        assertEquals("fig. 455", nameSpecDet3.getNomenclaturalMicroReference());
1374

    
1375
        //Special MicroRefs
1376
        String strSpecDetail4 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455-567. 1987";
1377
        fullReference = strSpecDetail4 + ".";
1378
        INonViralName nameSpecDet4 = parser.parseReferencedName(fullReference, null, rankSpecies);
1379
        assertFalse(nameSpecDet4.hasProblem());
1380
        assertEquals(strSpecDetail4, nameSpecDet4.getFullTitleCache());
1381
        assertEquals("fig. 455-567", nameSpecDet4.getNomenclaturalMicroReference());
1382

    
1383
        //Special MicroRefs
1384
        String strSpecDetail5 = "Abies alba Mill. in Sp. Pl. 4(6): Gard n\u00B0 4. 1987";
1385
        fullReference = strSpecDetail5 + ".";
1386
        INonViralName nameSpecDet5 = parser.parseReferencedName(fullReference, null, rankSpecies);
1387
        assertFalse(nameSpecDet5.hasProblem());
1388
        assertEquals(strSpecDetail5, nameSpecDet5.getFullTitleCache());
1389
        assertEquals("Gard n\u00B0 4", nameSpecDet5.getNomenclaturalMicroReference());
1390

    
1391
        //Special MicroRefs
1392
        String strSpecDetail6 = "Abies alba Mill. in Sp. Pl. 4(6): 455a. 1987";
1393
        fullReference = strSpecDetail6 + ".";
1394
        INonViralName nameSpecDet6 = parser.parseReferencedName(fullReference, null, rankSpecies);
1395
        assertFalse(nameSpecDet6.hasProblem());
1396
        assertEquals(strSpecDetail6, nameSpecDet6.getFullTitleCache());
1397
        assertEquals("455a", nameSpecDet6.getNomenclaturalMicroReference());
1398

    
1399
        //Special MicroRefs
1400
        String strSpecDetail7 = "Abies alba Mill. in Sp. Pl. 4(6): pp.455-457. 1987";
1401
        fullReference = strSpecDetail7 + ".";
1402
        INonViralName nameSpecDet7 = parser.parseReferencedName(fullReference, null, rankSpecies);
1403
        assertFalse(nameSpecDet7.hasProblem());
1404
        assertEquals(strSpecDetail7, nameSpecDet7.getFullTitleCache());
1405
        assertEquals("pp.455-457", nameSpecDet7.getNomenclaturalMicroReference());
1406

    
1407
        //Special MicroRefs
1408
        String strSpecDetail8 = "Abies alba Mill. in Sp. Pl. 4(6): ppp.455-457. 1987";
1409
        INonViralName nameSpecDet8 = parser.parseReferencedName(strSpecDetail8, null, rankSpecies);
1410
        assertTrue(nameSpecDet8.hasProblem());
1411
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1412
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after -457
1413

    
1414

    
1415
        //Special MicroRefs
1416
        String strSpecDetail9 = "Abies alba Mill. in Sp. Pl. 4(6): pp. 455 - 457. 1987";
1417
        INonViralName nameSpecDet9 = parser.parseReferencedName(strSpecDetail9, null, rankSpecies);
1418
        assertFalse(nameSpecDet9.hasProblem());
1419
        assertEquals(strSpecDetail9, nameSpecDet9.getFullTitleCache());
1420
        assertEquals("pp. 455 - 457", nameSpecDet9.getNomenclaturalMicroReference());
1421

    
1422
        //Special MicroRefs
1423
        String strSpecDetail10 = "Abies alba Mill. in Sp. Pl. 4(6): p 455. 1987";
1424
        INonViralName nameSpecDet10 = parser.parseReferencedName(strSpecDetail10, null, rankSpecies);
1425
        assertFalse(nameSpecDet10.hasProblem());
1426
        assertEquals(strSpecDetail10, nameSpecDet10.getFullTitleCache());
1427
        assertEquals("p 455", nameSpecDet10.getNomenclaturalMicroReference());
1428

    
1429
        //Special MicroRefs
1430
        String strSpecDetail11 = "Abies alba Mill. in Sp. Pl. 4(6): p. 455 - 457. 1987";
1431
        INonViralName nameSpecDet11 = parser.parseReferencedName(strSpecDetail11, null, rankSpecies);
1432
        assertTrue(nameSpecDet11.hasProblem());
1433
        list = nameSpecDet11.getParsingProblems();
1434
        assertTrue("Problem is Detail. Must be pp.", list.contains(ParserProblem.CheckDetailOrYear));
1435
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1436
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after - 457
1437

    
1438

    
1439
        //no volume, no edition
1440
        String strNoVolume = "Abies alba Mill., Sp. Pl.: 455. 1987";
1441
        INonViralName nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1442
        assertFalse(nameNoVolume.hasProblem());
1443
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1444
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1445
        assertEquals(null, ((IBook)nameNoVolume.getNomenclaturalReference()).getEdition());
1446

    
1447
        //volume, no edition
1448
        strNoVolume = "Abies alba Mill., Sp. Pl. 2: 455. 1987";
1449
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1450
        assertFalse(nameNoVolume.hasProblem());
1451
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1452
        assertEquals("2", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1453
        assertEquals(null, ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1454

    
1455
        //no volume, edition
1456
        strNoVolume = "Abies alba Mill., Sp. Pl., ed. 3: 455. 1987";
1457
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1458
        assertFalse(nameNoVolume.hasProblem());
1459
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1460
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1461
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1462

    
1463
        //volume, edition
1464
        strNoVolume = "Abies alba Mill., Sp. Pl. ed. 3, 4(5): 455. 1987";
1465
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1466
        assertFalse(nameNoVolume.hasProblem());
1467
        assertEquals(strNoVolume.replace(" ed.", ", ed."), nameNoVolume.getFullTitleCache());
1468
        assertEquals("4(5)", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1469
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1470

    
1471
        String strUnparsableInRef = "Abies alba Mill. in -er46: 455. 1987";
1472
        INonViralName nameUnparsableInRef = parser.parseReferencedName(strUnparsableInRef, null, rankSpecies);
1473
        assertTrue(nameUnparsableInRef.hasProblem());
1474
        list = nameUnparsableInRef.getParsingProblems();
1475
        assertTrue("Unparsable title", list.contains(ParserProblem.UnparsableReferenceTitle));
1476
        assertEquals(strUnparsableInRef, nameUnparsableInRef.getFullTitleCache());
1477
        assertEquals(20, nameUnparsableInRef.getProblemStarts());
1478
        assertEquals(25, nameUnparsableInRef.getProblemEnds());
1479

    
1480

    
1481
        //volume, edition
1482
        String strNoSeparator = "Abies alba Mill. Sp. Pl. ed. 3, 4(5): 455. 1987";
1483
        INonViralName nameNoSeparator = parser.parseReferencedName(strNoSeparator, ICNAFP, rankSpecies);
1484
        assertTrue(nameNoSeparator.hasProblem());
1485
        list = nameNoSeparator.getParsingProblems();
1486
        assertTrue("Problem is missing name-reference separator", list.contains(ParserProblem.NameReferenceSeparation));
1487
        assertEquals(strNoSeparator, nameNoSeparator.getFullTitleCache());
1488
        assertEquals(10, nameNoSeparator.getProblemStarts()); //TODO better start behind Mill. (?)
1489
        assertEquals(47, nameNoSeparator.getProblemEnds());   //TODO better stop before :
1490

    
1491
        String strUnparsableInRef2 = "Hieracium pepsicum L., My Bookkkk 1. 1903";
1492
        INonViralName nameUnparsableInRef2 = parser.parseReferencedName(strUnparsableInRef2, null, rankSpecies);
1493
        assertTrue(nameUnparsableInRef2.hasProblem());
1494
        list = nameUnparsableInRef2.getParsingProblems();
1495
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1496
        assertEquals(strUnparsableInRef2, nameUnparsableInRef2.getFullTitleCache());
1497
        assertEquals(23, nameUnparsableInRef2.getProblemStarts());
1498
        assertEquals(41, nameUnparsableInRef2.getProblemEnds());
1499

    
1500

    
1501
        String strUnparsableInRef3 = "Hieracium pespcim N., My Bookkkk 1. 1902";
1502
        INonViralName nameUnparsableInRef3 = parser.parseReferencedName(strUnparsableInRef3, null, null);
1503
        assertTrue(nameUnparsableInRef3.hasProblem());
1504
        list = nameUnparsableInRef3.getParsingProblems();
1505
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1506
        assertEquals(strUnparsableInRef3, nameUnparsableInRef3.getFullTitleCache());
1507
        assertEquals(22, nameUnparsableInRef3.getProblemStarts());
1508
        assertEquals(40, nameUnparsableInRef3.getProblemEnds());
1509

    
1510
        String strUnparsableInRef4 = "Hieracium pepsicum (Hsllreterto) L., My Bookkkk 1. 1903";
1511
        INonViralName nameUnparsableInRef4 = parser.parseReferencedName(strUnparsableInRef4, null, null);
1512
        assertTrue(nameUnparsableInRef4.hasProblem());
1513
        list = nameUnparsableInRef4.getParsingProblems();
1514
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1515
        assertEquals(strUnparsableInRef4, nameUnparsableInRef4.getFullTitleCache());
1516
        assertEquals(37, nameUnparsableInRef4.getProblemStarts());
1517
        assertEquals(55, nameUnparsableInRef4.getProblemEnds());
1518

    
1519
        String strSameName = "Hieracium pepcum (Hsllreterto) L., My Bokkk 1. 1903";
1520
        INonViralName nameSameName = nameUnparsableInRef4;
1521
        parser.parseReferencedName(nameSameName, strSameName, null, true);
1522
        assertTrue(nameSameName.hasProblem());
1523
        list = nameSameName.getParsingProblems();
1524
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1525
        assertEquals(strSameName, nameSameName.getFullTitleCache());
1526
        assertEquals(35, nameSameName.getProblemStarts());
1527
        assertEquals(51, nameSameName.getProblemEnds());
1528

    
1529
        String strGenusUnparse = "Hieracium L., jlklk";
1530
        INonViralName nameGenusUnparse =
1531
            parser.parseReferencedName(strGenusUnparse, null, null);
1532
        assertTrue(nameGenusUnparse.hasProblem());
1533
        list = nameGenusUnparse.getParsingProblems();
1534
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1535
        assertTrue("Problem uninomial", list.contains(ParserProblem.CheckRank));
1536
        assertEquals(strGenusUnparse, nameGenusUnparse.getFullTitleCache());
1537
        assertEquals(0, nameGenusUnparse.getProblemStarts());
1538
        assertEquals(19, nameGenusUnparse.getProblemEnds());
1539

    
1540
        String strGenusUnparse2 = "Hieracium L., Per Luigi: 44. 1987";
1541
        INonViralName nameGenusUnparse2 =
1542
            parser.parseReferencedName(strGenusUnparse2, null, Rank.FAMILY());
1543
        assertFalse(nameGenusUnparse2.hasProblem());
1544
        assertEquals(strGenusUnparse2, nameGenusUnparse2.getFullTitleCache());
1545
        assertEquals(-1, nameGenusUnparse2.getProblemStarts());
1546
        assertEquals(-1, nameGenusUnparse2.getProblemEnds());
1547

    
1548
        String strBookSection2 = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz, ed. 2, 2: 288. 1905-1907";
1549
        String strBookSection2NoComma = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905-1907";
1550
        INonViralName nameBookSection2 =
1551
              parser.parseReferencedName(strBookSection2, null, null);
1552
        assertFalse(nameBookSection2.hasProblem());
1553
        nameBookSection2.setFullTitleCache(null, false);
1554
        assertEquals(strBookSection2NoComma.replace(" ed.", ", ed.").replace("-",SEP), nameBookSection2.getFullTitleCache());
1555
        assertEquals(-1, nameBookSection2.getProblemStarts());
1556
        assertEquals(-1, nameBookSection2.getProblemEnds());
1557
        assertNull((nameBookSection2.getNomenclaturalReference()).getDatePublished().getStart());
1558
        assertEquals("1905"+SEP+"1907", ((IBookSection)nameBookSection2.getNomenclaturalReference()).getInBook().getDatePublished().getYear());
1559

    
1560
        String strBookSection = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905";
1561
        INonViralName nameBookSection =
1562
            parser.parseReferencedName(strBookSection, null, null);
1563
        assertFalse(nameBookSection.hasProblem());
1564
        assertEquals(strBookSection.replace(" ed.", ", ed."), nameBookSection.getFullTitleCache());
1565
        assertEquals(-1, nameBookSection.getProblemStarts());
1566
        assertEquals(-1, nameBookSection.getProblemEnds());
1567
        assertNull(((IBookSection)nameBookSection.getNomenclaturalReference()).getInBook().getDatePublished().getStart());
1568
        assertEquals("1905", ((IBookSection)nameBookSection.getNomenclaturalReference()).getDatePublished().getYear());
1569

    
1570
        String strXXXs = "Abies alba, Soer der 1987";
1571
        INonViralName problemName = parser.parseReferencedName(strXXXs, null, null);
1572
        assertTrue(problemName.hasProblem());
1573
        list = problemName.getParsingProblems();
1574
        assertTrue("Problem must be name-reference separation", list.contains(ParserProblem.NameReferenceSeparation));
1575
        parser.parseReferencedName(problemName, strBookSection, null, true);
1576
        assertFalse(problemName.hasProblem());
1577

    
1578
        problemName = parser.parseFullName(strXXXs, null, null);
1579
        assertTrue(problemName.hasProblem());
1580
        list = problemName.getParsingProblems();
1581
        assertTrue("Name part must be unparsable", list.contains(ParserProblem.UnparsableNamePart));
1582

    
1583

    
1584
        String testParsable = "Pithecellobium macrostachyum Benth.";
1585
        assertTrue(isParsable(testParsable, ICNAFP));
1586

    
1587
        testParsable = "Pithecellobium macrostachyum (Benth.)";
1588
        assertTrue(isParsable(testParsable, ICNAFP));
1589

    
1590
        testParsable = "Pithecellobium macrostachyum (Benth., 1845)";
1591
        assertTrue(isParsable(testParsable, NomenclaturalCode.ICZN));
1592

    
1593
        testParsable = "Pithecellobium macrostachyum L., Sp. Pl. 3: n\u00B0 123. 1753."; //00B0 is degree character
1594
        assertTrue(isParsable(testParsable, ICNAFP));
1595

    
1596
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. Mitt.-Eur. 6: 1285. 1929";
1597
        assertTrue("Reference title should support special characters as separators like - and &", isParsable(testParsable, ICNAFP));
1598

    
1599
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. Mitt.&Eur. 6: 1285. 1929";
1600
        assertTrue("Reference title should support special characters as separators like - and &", isParsable(testParsable, ICNAFP));
1601

    
1602
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. Mitt.-Eur.& 6: 1285. 1929";
1603
        assertFalse("Reference title should not support special characters like - and & at the end of the title", isParsable(testParsable, ICNAFP));
1604
        assertTrue("Problem must be reference title", getProblems(testParsable, ICNAFP).
1605
                contains(ParserProblem.UnparsableReferenceTitle));
1606

    
1607
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. Mitt.:Eur. 6: 1285. 1929";
1608
        assertFalse("Reference title should not support detail separator", isParsable(testParsable, ICNAFP));
1609
        assertTrue("Problem must be reference title", getProblems(testParsable, ICNAFP).
1610
                contains(ParserProblem.UnparsableReferenceTitle));
1611

    
1612
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. (Mitt.) 6: 1285. 1929";
1613
        assertTrue("Reference title should support brackets", isParsable(testParsable, ICNAFP));
1614

    
1615
        testParsable = "Hieracium lachenalii subsp. acuminatum (Jord.) Zahn in Hegi, Ill. Fl. (Mitt.) 6: 1285. 1929";
1616
        assertTrue("Reference title should support brackets", isParsable(testParsable, ICNAFP));
1617

    
1618
        testParsable = "Hieracium lachenalii Zahn, nom. illeg.";
1619
        assertTrue("Reference should not be obligatory if a nom status exist", isParsable(testParsable, ICNAFP));
1620

    
1621
        testParsable = "Hieracium lachenalii, nom. illeg.";
1622
        assertTrue("Authorship should not be obligatory if followed by nom status", isParsable(testParsable, ICNAFP));
1623

    
1624
        testParsable = "Hieracium lachenalii, Ill. Fl. (Mitt.) 6: 1285. 1929";
1625
        assertFalse("Author is obligatory if followed by reference", isParsable(testParsable, ICNAFP));
1626
        assertTrue("Problem must be name-reference separation", getProblems(testParsable, ICNAFP).
1627
                contains(ParserProblem.NameReferenceSeparation));
1628

    
1629
        testParsable = "Hieracium lachenalii in Hegi, Ill. Fl. (Mitt.) 6: 1285. 1929";
1630
        assertFalse("Author is obligatory if followed by reference", isParsable(testParsable, ICNAFP));
1631
        assertTrue("Problem must be name-reference separation", getProblems(testParsable, ICNAFP).
1632
                contains(ParserProblem.NameReferenceSeparation));
1633

    
1634
        testParsable = "Abies alba Mill. var. alba";
1635
        assertTrue("Autonym problem", isParsable(testParsable, ICNAFP));
1636

    
1637
        testParsable = "Scleroblitum abc Ulbr. in Engler & Prantl, Nat. Pflanzenfam., ed. 2, 16c: 495. 1934.";
1638
        assertTrue("Volume with subdivision", isParsable(testParsable, ICNAFP));
1639

    
1640

    
1641
        testParsable = "Hieracium antarcticum d'Urv. in M\u00E9m. Soc. Linn. Paris 4: 608. 1826";
1642
//      testParsable = "Hieracium antarcticum Urv. in M\u00E9m. Soc. Linn. Paris 4: 608. 1826";
1643
        assertTrue("Name with apostrophe is not parsable", isParsable(testParsable, ICNAFP));
1644

    
1645
        testParsable = "Cichorium intybus subsp. glaucum (Hoffmanns. & Link) Tzvelev in Komarov, Fl. SSSR 29: 17. 1964";
1646
        assertTrue("Reference containing a word in uppercase is not parsable", isParsable(testParsable, ICNAFP));
1647

    
1648
        testParsable = "Silene broussonetiana Schott ex Webb & Berthel., Hist. Nat. Iles Canaries 3(2,1): 141. 1840";
1649
        assertTrue("Reference with volume with 2 number in brackets is not parsable", isParsable(testParsable, ICNAFP));
1650
        testParsable = "Silene broussonetiana Schott ex Webb & Berthel., Hist. Nat. Iles Canaries 3(2, 1): 141. 1840";
1651
        assertTrue("Reference with volume with 2 number in brackets is not parsable", isParsable(testParsable, ICNAFP));
1652

    
1653
    }
1654

    
1655

    
1656
    /**
1657
     * Test author with name parts van, von, de, de la, d', da, del.
1658
     * See also https://dev.e-taxonomy.eu/redmine/issues/3373
1659
     */
1660
    @Test
1661
    public final void  testComposedAuthorNames(){
1662

    
1663
        //van author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1664
        String testParsable = "Aphelocoma unicolor subsp. griscomi van Rossem, 1928";
1665
        assertTrue("Author with 'van' should be parsable", isParsable(testParsable, ICZN));
1666

    
1667
        //von author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1668
        testParsable = "Aphelocoma unicolor subsp. griscomi von Rossem, 1928";
1669
        assertTrue("Author with 'von' should be parsable", isParsable(testParsable, ICZN));
1670

    
1671
        //de author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1672
        testParsable = "Aphelocoma unicolor subsp. griscomi de Rossem, 1928";
1673
        assertTrue("Author with 'de' should be parsable", isParsable(testParsable, ICZN));
1674

    
1675
        //de la author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1676
        testParsable = "Aphelocoma unicolor subsp. griscomi de la Rossem, 1928";
1677
        assertTrue("Author with 'de la' should be parsable", isParsable(testParsable, ICZN));
1678

    
1679
        //d' author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1680
        testParsable = "Aphelocoma unicolor subsp. griscomi d'Rossem, 1928";
1681
        assertTrue("Author with \"'d'\" should be parsable", isParsable(testParsable, ICZN));
1682

    
1683
        //da author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1684
        testParsable = "Aphelocoma unicolor subsp. griscomi da Rossem, 1928";
1685
        assertTrue("Author with 'da' should be parsable", isParsable(testParsable, ICZN));
1686

    
1687
        //del author (see https://dev.e-taxonomy.eu/redmine/issues/3373)
1688
        testParsable = "Aphelocoma unicolor subsp. griscomi del Rossem, 1928";
1689
        assertTrue("Author with 'del' should be parsable", isParsable(testParsable, ICZN));
1690

    
1691
        //O' author (see https://dev.e-taxonomy.eu/redmine/issues/4759)
1692
        testParsable = "Aphelocoma unicolor subsp. griscomi O'Connor, 1928";
1693
        assertTrue("Author with 'O'' should be parsable", isParsable(testParsable, ICZN));
1694

    
1695
        //del author (see https://dev.e-taxonomy.eu/redmine/issues/4759)
1696
        testParsable = "Aphelocoma unicolor subsp. griscomi zur Strassen, 1928";
1697
        assertTrue("Author with 'zur' should be parsable", isParsable(testParsable, ICZN));
1698

    
1699
    }
1700

    
1701
    private List<ParserProblem> getProblems(String string, NomenclaturalCode code) {
1702
        List<ParserProblem> result = parser.parseReferencedName(string, code, null).getParsingProblems();
1703
        return result;
1704
    }
1705

    
1706
    private boolean isParsable(String string, NomenclaturalCode code){
1707
        INonViralName name = parser.parseReferencedName(string, code, null);
1708
        if (name.hasProblem()) {
1709
            return false;
1710
        }else if (name.getNomenclaturalReference() != null) {
1711
            //not really neccessary as "problem" is for fulltitlecache and therefore also
1712
            Reference nomRef = name.getNomenclaturalReference();
1713
            if (nomRef.hasProblem()) {
1714
                return false;
1715
            }else if (nomRef.getInReference() != null) {
1716
                if (nomRef.getInReference().hasProblem()) {
1717
                    return false;
1718
                }
1719
            }
1720
        }
1721
        return true;
1722
    }
1723

    
1724
    private void assertFullRefNameStandard(INonViralName name){
1725
        assertEquals("Abies", name.getGenusOrUninomial());
1726
        assertEquals("alba", name.getSpecificEpithet());
1727
        assertEquals("Mill.", name.getAuthorshipCache());
1728
        assertEquals("455", name.getNomenclaturalMicroReference());
1729
        assertNotNull(name.getNomenclaturalReference());
1730
    }
1731

    
1732
    private void assertFullRefStandard(INonViralName name){
1733
        assertEquals("Abies", name.getGenusOrUninomial());
1734
        assertEquals("alba", name.getSpecificEpithet());
1735
        assertEquals("Mill.", name.getAuthorshipCache());
1736
        assertEquals("455", name.getNomenclaturalMicroReference());
1737
        assertNotNull(name.getNomenclaturalReference());
1738
        INomenclaturalReference ref = name.getNomenclaturalReference();
1739
        assertEquals("1987", ref.getYear());
1740
        assertEquals("Sp. Pl.", ref.getAbbrevTitle());
1741
    }
1742

    
1743

    
1744
    @Test
1745
    public void testNeverEndingParsing(){
1746
        //some full titles result in never ending parsing process https://dev.e-taxonomy.eu/redmine/issues/1556
1747

    
1748
        String irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1749
//      irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Uiuis Iuiui Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1750
        INonViralName nvn = this.parser.parseReferencedName(irinaExample, NomenclaturalCode.ICZN, null);
1751
        int parsingProblem = nvn.getParsingProblem();
1752
        Assert.assertEquals("Name should have only rank warning", 1, parsingProblem);
1753
        Assert.assertEquals("Titlecache", "Milichiidae Sharp, 1899", nvn.getTitleCache());
1754
        Assert.assertEquals("If this line reached everything should be ok", "Milichiidae", nvn.getGenusOrUninomial());
1755

    
1756
        String anotherExample = "Scorzonera hispanica var. brevifolia Boiss. & Balansa in Boissier, Diagn. Pl. Orient., ser. 2 6: 119. 1859.";
1757
        nvn = this.parser.parseReferencedName(anotherExample, ICNAFP, null);
1758
        parsingProblem = nvn.getParsingProblem();
1759
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
1760
        Assert.assertEquals("Titlecache", "Scorzonera hispanica var. brevifolia Boiss. & Balansa", nvn.getTitleCache());
1761
        Assert.assertEquals("If this line reached everything should be ok", "Scorzonera", nvn.getGenusOrUninomial());
1762

    
1763
        String unparsable = "Taraxacum nevskii L., Trudy Bot. Inst. Nauk S.S.S.R., Ser. 1, Fl. Sist. Vyssh. Rast. 4: 293. 1937.";
1764
//      String unparsableA = "Taraxacum nevskii L. in Trudy Bot. Inst. Nauk: 293. 1937.";
1765
        nvn = this.parser.parseReferencedName(unparsable, ICNAFP, null);
1766
        Assert.assertEquals("Titlecache", "Taraxacum nevskii L.", nvn.getTitleCache());
1767
        Assert.assertEquals("If this line reached everything should be ok", "Taraxacum", nvn.getGenusOrUninomial());
1768
        parsingProblem = nvn.getParsingProblem();
1769
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1770

    
1771
        String unparsable2 = "Hieracium pxxx Dahlst., Kongl. Svenska Vetensk. Acad. Handl. ser. 2, 26(3): 255. 1894";
1772
//      String unparsable2A = "Hieracium pxxx Dahlst., Kongl Svenska Vetensk Acad Handl, 26: 255. 1894.";
1773
        nvn = this.parser.parseReferencedName(unparsable2, ICNAFP, null);
1774
        Assert.assertEquals("Titlecache", "Hieracium pxxx Dahlst.", nvn.getTitleCache());
1775
        Assert.assertEquals("If this line reached everything should be ok", "Hieracium", nvn.getGenusOrUninomial());
1776
        parsingProblem = nvn.getParsingProblem();
1777
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1778

    
1779

    
1780
        String again = "Adiantum emarginatum Bory ex. Willd., Species Plantarum, ed. 4,5,1: 449,450. 1810";
1781
        nvn = this.parser.parseReferencedName(again, ICNAFP, null);
1782
        Assert.assertEquals("Titlecache", "Adiantum emarginatum Bory ex Willd.", nvn.getTitleCache());
1783
        Assert.assertEquals("If this line reached everything should be ok", "Adiantum", nvn.getGenusOrUninomial());
1784

    
1785
    }
1786

    
1787

    
1788
    @Test
1789
    public final void testSeries(){
1790
        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea, n.s., 9: 31. 1958";
1791
        INonViralName name = parser.parseReferencedName(parseStr);
1792
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1793
        Reference nomRef = name.getNomenclaturalReference();
1794
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1795

    
1796
        assertEquals(ReferenceType.Article, nomRef.getType());
1797
        assertEquals(name.getNomenclaturalMicroReference(), "31");
1798
        assertEquals("Nova Guinea", nomRef.getInJournal().getAbbrevTitle());
1799
        assertEquals("n.s.", nomRef.getSeriesPart());
1800
    }
1801

    
1802
    @Test
1803
    @Ignore
1804
    public final void testRussian(){
1805
        String parseStr = "Cortusa turkestanica Losinsk. in Тр. Бот. инст. Aкад. наук СССР, сер. 1, 3: 239. 1936";
1806
        INonViralName name = parser.parseReferencedName(parseStr);
1807
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1808
        Reference nomRef = name.getNomenclaturalReference();
1809
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1810

    
1811
        assertEquals(ReferenceType.Article, nomRef.getType());
1812
        assertEquals(name.getNomenclaturalMicroReference(), "239");
1813
        assertEquals("Тр. Бот. инст. Aкад. наук СССР", nomRef.getInJournal().getAbbrevTitle());
1814
        assertEquals("сер. 1", nomRef.getSeriesPart());
1815
    }
1816

    
1817
    @Test
1818
    public final void testDetails(){
1819
        //s.p.
1820
        String parseStr = "Xiphion filifolium var. latifolium Baker, Gard. Chron. 1876: s.p.. 1876";
1821
        INonViralName name = parser.parseReferencedName(parseStr);
1822
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1823
        Reference nomRef = name.getNomenclaturalReference();
1824
        assertEquals(ReferenceType.Book, nomRef.getType());
1825
        assertEquals(name.getNomenclaturalMicroReference(), "s.p.");
1826

    
1827
        //roman
1828
        parseStr = "Ophrys lutea subsp. pseudospeculum (DC.) Kergu\u00e9len, Collect. Partim. Nat. 8: xv. 1993";
1829
        name = parser.parseReferencedName(parseStr);
1830
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1831
        nomRef = name.getNomenclaturalReference();
1832
        assertEquals(ReferenceType.Book, nomRef.getType());
1833
        assertEquals(name.getNomenclaturalMicroReference(), "xv");
1834

    
1835
        //n. 1
1836
        parseStr = "Olea gallica Mill., Gard. Dict. ed. 8: n. 1. 1768";
1837
        name = parser.parseReferencedName(parseStr);
1838
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1839
        nomRef = name.getNomenclaturalReference();
1840
        assertEquals(ReferenceType.Book, nomRef.getType());
1841
        assertEquals(name.getNomenclaturalMicroReference(), "n. 1");
1842

    
1843
        parseStr = "Lavandula canariensis Mill., Gard. Dict. ed. 8: Lavandula no. 4. 1768";
1844
        name = parser.parseReferencedName(parseStr);
1845
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1846
        nomRef = name.getNomenclaturalReference();
1847
        assertEquals(ReferenceType.Book, nomRef.getType());
1848
        assertEquals(name.getNomenclaturalMicroReference(), "Lavandula no. 4");
1849

    
1850
        parseStr = "Aceras anthropomorphum (Pers.) Sm. in Rees, Cycl. 39(1): Aceras n. 2. 1818";
1851
        name = parser.parseReferencedName(parseStr);
1852
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1853
        nomRef = name.getNomenclaturalReference();
1854
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1855
        assertEquals(name.getNomenclaturalMicroReference(), "Aceras n. 2");
1856

    
1857
        parseStr = "Chlorolepis Nutt. in Trans. Amer. Philos. Soc., n.s., 7: errata. 1841";
1858
        name = parser.parseReferencedName(parseStr);
1859
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1860
        nomRef = name.getNomenclaturalReference();
1861
        assertEquals(ReferenceType.Article, nomRef.getType());
1862
        assertEquals(name.getNomenclaturalMicroReference(), "errata");
1863

    
1864
        parseStr = "Yermoloffia B\u00e9l., Voy. Indes Or.: t. s.n.. 1846";
1865
        name = parser.parseReferencedName(parseStr);
1866
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1867
        nomRef = name.getNomenclaturalReference();
1868
        assertEquals(ReferenceType.Book, nomRef.getType());
1869
        assertEquals(name.getNomenclaturalMicroReference(), "t. s.n.");
1870

    
1871
        parseStr = "Gagea mauritanica Durieu, Expl. Sci. Alg\u00e9rie, Atlas: t. 45bis, f. 4. 1850";
1872
        name = parser.parseReferencedName(parseStr);
1873
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1874
        nomRef = name.getNomenclaturalReference();
1875
        assertEquals(ReferenceType.Book, nomRef.getType());
1876
        assertEquals(name.getNomenclaturalMicroReference(), "t. 45bis, f. 4");
1877

    
1878
        parseStr = "Orchis latifolia f. blyttii Rchb. f. in Reichenbach, Icon. Fl. Germ. Helv. 13-14: 60, t. 59, f. III. 1851";
1879
        name = parser.parseReferencedName(parseStr);
1880
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1881
        nomRef = name.getNomenclaturalReference();
1882
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1883
        assertEquals(name.getNomenclaturalMicroReference(), "60, t. 59, f. III");
1884

    
1885
        parseStr = "Ephedra alata var. decaisnei Stapf in Denkschr. Kaiserl. Akad. Wiss., Wien. Math.-Naturwiss. Kl. 56(2): t. 1/1. 1889";
1886
        name = parser.parseReferencedName(parseStr);
1887
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1888
        nomRef = name.getNomenclaturalReference();
1889
        assertEquals(ReferenceType.Article, nomRef.getType());
1890
        assertEquals(name.getNomenclaturalMicroReference(), "t. 1/1");
1891
    }
1892

    
1893
    @Test
1894
    public final void testEditionVolumeSeries(){
1895
        //ed. 2, 2(1)
1896
        String parseStr = "Sieberia albida (L.) Spreng., Anleit. Kenntn. Gew., ed. 2, 2(1): 282. 1817";
1897
        INonViralName name = parser.parseReferencedName(parseStr);
1898
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1899
        Reference nomRef = name.getNomenclaturalReference();
1900
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1901
        assertEquals(ReferenceType.Book, nomRef.getType());
1902
        assertEquals("2", nomRef.getEdition());
1903
        assertEquals("2(1)", nomRef.getVolume());
1904

    
1905
        parseStr = "Gagea glacialis var. joannis (Grossh.) Grossh., Fl. Kavkaza, ed. 2, 2: 105. 1940";
1906
        name = parser.parseReferencedName(parseStr);
1907
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1908
        nomRef = name.getNomenclaturalReference();
1909
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1910
        assertEquals(ReferenceType.Book, nomRef.getType());
1911
        assertEquals("2", nomRef.getEdition());
1912
        assertEquals("2", nomRef.getVolume());
1913

    
1914
        //14-15
1915
        parseStr = "Semele gayae (Webb & Berthel.) Svent. & Kunkel, Cuad. Bot. Canaria 14-15: 81. 1972";
1916
        name = parser.parseReferencedName(parseStr);
1917
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1918
        nomRef = name.getNomenclaturalReference();
1919
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1920
        assertEquals(ReferenceType.Book, nomRef.getType());
1921
        assertEquals("14-15", nomRef.getVolume());
1922

    
1923
        //35-37(2)
1924
        parseStr = "Lavandula multifida var. heterotricha Sauvage in Bull. Soc. Sci. Nat. Maroc 35-37(2): 392. 1947";
1925
        name = parser.parseReferencedName(parseStr);
1926
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1927
        nomRef = name.getNomenclaturalReference();
1928
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1929
        assertEquals(ReferenceType.Article, nomRef.getType());
1930
        assertNull(nomRef.getEdition());
1931
        assertEquals("35-37(2)", nomRef.getVolume());
1932

    
1933
        //Sér. 7
1934
        parseStr = "Oxynepeta involucrata Bunge, M\u00E9m. Acad. Imp. Sci. Saint P\u00E9tersbourg, S\u00E9r. 7, 21(1): 59. 1878";
1935
        name = parser.parseReferencedName(parseStr);
1936
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1937
        nomRef = name.getNomenclaturalReference();
1938
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1939
        assertEquals(ReferenceType.Book, nomRef.getType());
1940
        assertNull(nomRef.getEdition());
1941
        assertEquals("21(1)", nomRef.getVolume());
1942
        //Currently we do not put the series part into the series field, this may change in future
1943
//        assertEquals("Sér. 7", nomRef.getSeriesPart());
1944

    
1945
        //Suppl. 1
1946
        parseStr = "Dissorhynchium Schauer, Nov. Actorum Acad. Caes. Leop.-Carol. Nat. Cur. 19(Suppl. 1): 434. 1843";
1947
        name = parser.parseReferencedName(parseStr);
1948
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1949
        nomRef = name.getNomenclaturalReference();
1950
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1951
        assertEquals(ReferenceType.Book, nomRef.getType());
1952
        assertNull(nomRef.getEdition());
1953
        assertEquals("19(Suppl. 1)", nomRef.getVolume());
1954

    
1955
        //54*B*
1956
        parseStr = "Thymus chaubardii var. boeoticus (Heinr. Braun) Ronniger in Beih. Bot. Centralbl. 54B: 662. 1936";
1957
        name = parser.parseReferencedName(parseStr);
1958
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1959
        nomRef = name.getNomenclaturalReference();
1960
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1961
        assertEquals(ReferenceType.Article, nomRef.getType());
1962
        assertNull(nomRef.getEdition());
1963
        assertEquals("54B", nomRef.getVolume());
1964

    
1965

    
1966
        //1, Erg.
1967
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.volume);
1968
        Matcher matcher = seriesPattern.matcher("12(1, Erg.)");
1969
        Assert.assertTrue("12(1, Erg.) should match", matcher.matches());
1970

    
1971
        parseStr = "Scilla amethystina Vis. in Flora Abt Awer Ser 12(1, Erg.): 11. 1829";
1972
        name = parser.parseReferencedName(parseStr);
1973
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1974
        nomRef = name.getNomenclaturalReference();
1975
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1976
        assertEquals(ReferenceType.Article, nomRef.getType());
1977
        assertNull(nomRef.getEdition());
1978
        assertEquals("12(1, Erg.)", nomRef.getVolume());
1979

    
1980
        // jubilee ed.
1981
        parseStr = "Orchis sambucina var. bracteata (M. Schulze) Harz, Fl. Deutschl., jubilee ed., 4: 271. 1895";
1982
        name = parser.parseReferencedName(parseStr);
1983
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1984
        nomRef = name.getNomenclaturalReference();
1985
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1986
        assertEquals(ReferenceType.Book, nomRef.getType());
1987
        assertEquals("jubilee ed.",nomRef.getEdition());
1988
        assertEquals("4", nomRef.getVolume());
1989
        assertEquals(parseStr, name.getFullTitleCache());
1990

    
1991
        //nouv. ed.
1992
        parseStr = "Fraxinus polemonifolia Poir. in Duhamel du Monceau, Trait\u00E9 Arbr. Arbust., nouv. ed., 4: 66. 1809";
1993
        name = parser.parseReferencedName(parseStr);
1994
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1995
        nomRef = name.getNomenclaturalReference();
1996
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1997
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1998
        assertEquals("nouv. ed.",nomRef.getInReference().getEdition());
1999
        assertEquals("4", nomRef.getInReference().getVolume());
2000
        assertEquals(parseStr, name.getFullTitleCache());
2001

    
2002
        //ed. 3B
2003
        parseStr = "Juncus supinus var. kochii (F. W. Schultz) Syme in Smith, Engl. Bot., ed. 3B, 10: 33. 1870";
2004
        name = parser.parseReferencedName(parseStr);
2005
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2006
        nomRef = name.getNomenclaturalReference();
2007
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2008
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2009
        //maybe we remove ed. for this case in future
2010
        assertEquals("ed. 3B",nomRef.getInReference().getEdition());
2011
        assertEquals("10", nomRef.getInReference().getVolume());
2012
        assertEquals(parseStr, name.getFullTitleCache());
2013

    
2014
        //ed. 15 bis
2015
        parseStr = "Solanum persicum Willd. ex Roem. & Schult., Syst. Veg., ed. 15 bis, 4: 662. 1819";
2016
        name = parser.parseReferencedName(parseStr);
2017
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2018
        nomRef = name.getNomenclaturalReference();
2019
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2020
        assertEquals(ReferenceType.Book, nomRef.getType());
2021
        //maybe we remove ed. for this case in future
2022
        assertEquals("ed. 15 bis",nomRef.getEdition());
2023
        assertEquals("4", nomRef.getVolume());
2024
        assertEquals(parseStr, name.getFullTitleCache());
2025

    
2026

    
2027
//        Epipactis helleborine subsp. ohwii (Fukuy.) H. J. Su in Fl. Taiwan, ed. 2, 5: 861. 2000
2028
    }
2029

    
2030
    @Test
2031
    public final void testTitleBrackets(){
2032
        //Bot. Zhurn. (Moscow & Leningrad)
2033
        String parseStr = "Juncus subcompressus Zakirov & Novopokr. in Bot. Zhurn. (Moscow & Leningrad) 36(1): 77. 1951";
2034
        TaxonName name = parser.parseReferencedName(parseStr);
2035
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2036
        Reference nomRef = name.getNomenclaturalReference();
2037
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2038
        assertEquals(ReferenceType.Article, nomRef.getType());
2039
        assertEquals("Bot. Zhurn. (Moscow & Leningrad)", nomRef.getInReference().getAbbrevTitle());
2040
        assertNull(nomRef.getEdition());
2041
        assertEquals("36(1)", nomRef.getVolume());
2042
    }
2043

    
2044
    @Test
2045
    public final void testTitleSpecials(){
2046
        //Pt. 2  (currently handled as series part, may change in future
2047
        String parseStr = "Iris pumila subsp. sintenisiiformis Prod\u00E1n in Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat. 27: 89. 1941";
2048
        TaxonName name = parser.parseReferencedName(parseStr);
2049
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2050
        Reference nomRef = name.getNomenclaturalReference();
2051
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2052
        assertEquals(ReferenceType.Article, nomRef.getType());
2053
        assertEquals("Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat.", nomRef.getInReference().getAbbrevTitle());
2054
        assertNull(nomRef.getEdition());
2055
        assertEquals("27", nomRef.getVolume());
2056

    
2057
        //same as Pt. 2, "Sect. xx" handled as series part but may change
2058
        parseStr = "Quercus boissieri var. microphylla (A. Camus) Zohary in Bull. Res. Council Israel, Sect. D, Bot. 9: 169. 1961";
2059
        name = parser.parseReferencedName(parseStr);
2060
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2061
        nomRef = name.getNomenclaturalReference();
2062
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2063
        assertEquals(ReferenceType.Article, nomRef.getType());
2064
        assertEquals("Bull. Res. Council Israel, Sect. D, Bot.", nomRef.getInReference().getAbbrevTitle());
2065
        assertNull(nomRef.getEdition());
2066
        assertEquals("9", nomRef.getVolume());
2067

    
2068
        //see above
2069
        parseStr = "Fimbristylis dichotoma var. annua (All.) T. Koyama in J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot. 8: 111. 1961";
2070
        name = parser.parseReferencedName(parseStr);
2071
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2072
        nomRef = name.getNomenclaturalReference();
2073
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2074
        assertEquals(ReferenceType.Article, nomRef.getType());
2075
        assertEquals("J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot.", nomRef.getInReference().getAbbrevTitle());
2076
        assertNull(nomRef.getEdition());
2077
        assertEquals("8", nomRef.getVolume());
2078

    
2079

    
2080
        // "- "
2081
        parseStr = "Theresia tulipilfoia (M. Bieb.) Klatt in Hamburger Garten- Blumenzeitung 16: 438. 1860";
2082
        name = parser.parseReferencedName(parseStr);
2083
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2084
        nomRef = name.getNomenclaturalReference();
2085
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2086
        assertEquals(ReferenceType.Article, nomRef.getType());
2087
        assertEquals("Hamburger Garten- Blumenzeitung", nomRef.getInReference().getAbbrevTitle());
2088
        assertNull(nomRef.getEdition());
2089
        assertEquals("16", nomRef.getVolume());
2090

    
2091
        parseStr = "Hyssopus officinalis var. pilifer Pant. in Verh. Vereins Natur- Heilk. Presburg, n.s., 2: 61. 1874";
2092
        name = parser.parseReferencedName(parseStr);
2093
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2094
        nomRef = name.getNomenclaturalReference();
2095
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2096
        assertEquals(ReferenceType.Article, nomRef.getType());
2097
        //, n.s., is not necessarily part of the title in future
2098
        assertEquals("Verh. Vereins Natur- Heilk. Presburg", nomRef.getInReference().getAbbrevTitle());
2099
        assertNull(nomRef.getEdition());
2100
        assertEquals("n.s.", nomRef.getSeriesPart());
2101
        assertEquals("2", nomRef.getVolume());
2102

    
2103
          //Note: space in E+M, no space in IPNI; is it really a book?
2104
        parseStr = "Amaryllis dubia Houtt., Handl. Pl.- Kruidk. 12: 181. 1780";
2105
        name = parser.parseReferencedName(parseStr);
2106
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2107
        nomRef = name.getNomenclaturalReference();
2108
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2109
        assertEquals(ReferenceType.Book, nomRef.getType());
2110
        assertEquals("Handl. Pl.- Kruidk.", nomRef.getAbbrevTitle());
2111
        assertNull(nomRef.getEdition());
2112
        assertEquals("12", nomRef.getVolume());
2113

    
2114
        // "..."
2115
        parseStr = "Chamaesyce biramensis (Urb.) Alain in Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\" 11: 12. 1952";
2116
        name = parser.parseReferencedName(parseStr);
2117
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2118
        nomRef = name.getNomenclaturalReference();
2119
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2120
        assertEquals(ReferenceType.Article, nomRef.getType());
2121
        assertEquals("Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\"", nomRef.getInReference().getAbbrevTitle());
2122
        assertNull(nomRef.getEdition());
2123
        assertEquals("11", nomRef.getVolume());
2124

    
2125
        //' & '
2126
        parseStr = "Mannaphorus Raf. in Amer. Monthly Mag. & Crit. Rev. 1: 175. 1818";
2127
        name = parser.parseReferencedName(parseStr);
2128
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2129
        nomRef = name.getNomenclaturalReference();
2130
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2131
        assertEquals(ReferenceType.Article, nomRef.getType());
2132
        assertEquals("Amer. Monthly Mag. & Crit. Rev.", nomRef.getInReference().getAbbrevTitle());
2133
        assertNull(nomRef.getEdition());
2134
        assertEquals("1", nomRef.getVolume());
2135

    
2136
        //only for debugging
2137
        boolean  matches;
2138
        matches = "Flo & Amer. Fauna. Ab.".matches (NonViralNameParserImplRegExBase.referenceTitleFirstPart + "*");
2139
        Assert.assertTrue("referenceTitleFirstPart", matches);
2140

    
2141
        matches = "Fl. Amer. & Fauna. Ab. 101".matches (NonViralNameParserImplRegExBase.pSoftArticleReference);
2142
        Assert.assertTrue("pSoftArticleReference", matches);
2143
        //only for debugging end
2144

    
2145
        parseStr = "Corallorhiza trifida subsp. virescens (Drejer) L\u00F8jtnant in Fl. & Fauna (Esbjerg) 101: 71. 1996";
2146
        name = parser.parseReferencedName(parseStr);
2147
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2148
        nomRef = name.getNomenclaturalReference();
2149
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2150
        assertEquals(ReferenceType.Article, nomRef.getType());
2151
        assertEquals("Fl. & Fauna (Esbjerg)", nomRef.getInReference().getAbbrevTitle());
2152
        assertNull(nomRef.getEdition());
2153
        assertEquals("101", nomRef.getVolume());
2154

    
2155
        parseStr = "Crocus isauricus Siehe ex Bowles, Handb. Crocus & Colch.: 126. 1924";
2156
        name = parser.parseReferencedName(parseStr);
2157
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2158
        nomRef = name.getNomenclaturalReference();
2159
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2160
        assertEquals(ReferenceType.Book, nomRef.getType());
2161
        assertEquals("Handb. Crocus & Colch.", nomRef.getAbbrevTitle());
2162
        assertNull(nomRef.getEdition());
2163
        assertNull(nomRef.getVolume());
2164

    
2165
        parseStr = "Ornithogalum bifolium (L.) Neck. in Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat. 2: 461. 1770";
2166
        name = parser.parseReferencedName(parseStr);
2167
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2168
        nomRef = name.getNomenclaturalReference();
2169
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2170
        assertEquals(ReferenceType.Article, nomRef.getType());
2171
        assertEquals("Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat.", nomRef.getInReference().getAbbrevTitle());
2172
        assertNull(nomRef.getEdition());
2173
        assertEquals("2", nomRef.getVolume());
2174

    
2175
    }
2176

    
2177
    @Test
2178
    public final void testArticlePattern(){
2179
        Pattern articlePattern = Pattern.compile(NonViralNameParserImplRegExBase.pArticleReference);
2180
        Matcher matcher = articlePattern.matcher("Acta Bot. Hung. 46 (1-2)");
2181
        Assert.assertTrue("", matcher.matches());
2182
        matcher = articlePattern.matcher("Nova Guinea Bla 9");
2183
        Assert.assertTrue("", matcher.matches());
2184
        matcher = articlePattern.matcher("Nova Guinea Bla , n.s., 9");
2185
        Assert.assertTrue("", matcher.matches());
2186
    }
2187

    
2188

    
2189
    @Test
2190
    public final void testSeriesPart(){
2191
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.pSeriesPart);
2192
        Matcher matcher = seriesPattern.matcher(", ser. 2,");
2193
        Assert.assertTrue("", matcher.matches());
2194

    
2195
        matcher = seriesPattern.matcher("n.s.");
2196
        Assert.assertTrue("", matcher.matches());
2197

    
2198
//        matcher = seriesPattern.matcher("a.s.");
2199
//        Assert.assertTrue("", matcher.matches());
2200

    
2201
        //do NOT match edition  //but there are such cases like "Vilm. Blumengärtn. ed. 3" according to TL-2
2202
        matcher = seriesPattern.matcher("ed. 4");
2203
        Assert.assertFalse("", matcher.matches());
2204

    
2205
        matcher = seriesPattern.matcher("Ser. C");
2206
        Assert.assertTrue("", matcher.matches());
2207

    
2208
        matcher = seriesPattern.matcher("S\u00E9r. B 1");
2209
        Assert.assertTrue("", matcher.matches());
2210

    
2211
        matcher = seriesPattern.matcher("Jerusalem Ser.");
2212
        Assert.assertTrue("", matcher.matches());
2213

    
2214
        matcher = seriesPattern.matcher("nov. Ser.");
2215
        Assert.assertTrue("", matcher.matches());
2216
    }
2217

    
2218
    @Test
2219
    public final void testFullTeams() {
2220
        logger.warn("Not yet implemented"); // TODO
2221
    }
2222

    
2223
    @Test
2224
    public final void testParseAuthorsTaxonNameString() throws StringNotParsableException {
2225
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
2226
        parser.parseAuthors(nvn, "Eckweiler & ten Hagen, 2003");
2227
        Team team = (Team)nvn.getCombinationAuthorship();
2228
        Assert.assertNotNull("Comb. author must not be null", team);
2229
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
2230
        Assert.assertEquals("Second member must be 'ten Hagen'", "ten Hagen", team.getTeamMembers().get(1).getTitleCache());
2231

    
2232
        //Crosson du Cormier, 1964
2233
        IZoologicalName zooName = TaxonNameFactory.NewZoologicalInstance(null);
2234
        parser.parseAuthors(zooName, "Crosson du Cormier, 1964");
2235
        Person person = (Person)zooName.getCombinationAuthorship();
2236
        Assert.assertNotNull("Comb. author must not be null", person);
2237
        Assert.assertEquals("Persons title must be 'Crosson du Cormier'", "Crosson du Cormier", person.getTitleCache());
2238
        Assert.assertEquals("Year must be 1964", Integer.valueOf(1964), zooName.getPublicationYear() );
2239

    
2240
        //(van der Hoeven, 1839)
2241
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2242
        parser.parseAuthors(zooName, "(van der Hoeven, 1839)");
2243
        Assert.assertNull("Combination author must be null", zooName.getCombinationAuthorship());
2244
        person = (Person)zooName.getBasionymAuthorship();
2245
        Assert.assertNotNull("Basionym author must not be null", person);
2246
        Assert.assertEquals("Persons title must be 'van der Hoeven'", "van der Hoeven", person.getTitleCache());
2247
        Assert.assertEquals("Year must be 1839", Integer.valueOf(1839), zooName.getOriginalPublicationYear() );
2248

    
2249
        //le Doux, 1931
2250
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2251
        parser.parseAuthors(zooName, "le Doux, 1931");
2252
        person = (Person)zooName.getCombinationAuthorship();
2253
        Assert.assertNotNull("Comb. author must not be null", person);
2254
        Assert.assertEquals("Persons title must be 'le Doux'", "le Doux", person.getTitleCache());
2255
        Assert.assertEquals("Year must be 1931", Integer.valueOf(1931), zooName.getPublicationYear() );
2256

    
2257

    
2258
    }
2259

    
2260
    @Test  //#4764
2261
    public void testParseSection(){
2262
        //this test does not really test problematic cases where sect.idInVoc = "sect." instead of "sect.(bot.)"
2263
        //however, by changing the csv file entry to sect. just for testing it can be used as a functional test
2264
        String sectionNameStr = "Taraxacum sect. Testtaxa M\u00fcller, Incredible Taxa: 12. 2016";
2265
        INonViralName sectionName = parser.parseReferencedName(sectionNameStr, NomenclaturalCode.ICNAFP, null);
2266
        int parsingProblem = sectionName.getParsingProblem();
2267
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
2268
        Rank rank = sectionName.getRank();
2269
        Assert.assertEquals("", Rank.SECTION_BOTANY(), rank  );
2270
    }
2271

    
2272
    //#6577
2273
    @Test
2274
    public final void testParseSpNov(){
2275
        //Canabio, issue with space
2276
        INonViralName name = parser.parseFullName("Iresine sp. nov. 1");
2277
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2278
        Assert.assertEquals("sp. nov. 1", name.getSpecificEpithet());
2279

    
2280
        name = parser.parseFullName("Gomphichis sp. 22");
2281
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2282
        Assert.assertEquals("sp. 22", name.getSpecificEpithet());
2283

    
2284
        name = parser.parseFullName("Phleum sp. nov.");
2285
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2286
        Assert.assertEquals("sp. nov.", name.getSpecificEpithet());
2287

    
2288
        name = parser.parseFullName("Phleum sp.");
2289
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2290
        Assert.assertEquals("sp.", name.getSpecificEpithet());
2291

    
2292
    }
2293

    
2294

    
2295
    @Test  //#5072
2296
    public final void testLongRunningParsingCapitals(){
2297
        DateTime start = DateTime.now();
2298
        String nameStr = "Nazeris fujianensis JIAYAO HU, LIZHEN LI, MEIJUN ZHAO,2010";  //name from CoL that created problems
2299
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICZN, null);
2300
        DateTime end = DateTime.now();
2301
        Duration duration = new Duration(start, end);
2302
        long seconds = duration.getStandardSeconds();
2303
        //this is the critical part of the test that must not be changed
2304
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2305

    
2306
    }
2307

    
2308
    @Test  //#5072
2309
    //http://www.regular-expressions.info/catastrophic.html
2310
    public final void testLongRunningParsing(){
2311

    
2312
        //name only
2313
        String nameStr = "Dictyocoela berillonum R.S. Terry, J.E. Sm., R.G. Sharpe, T. Rigaud, D.T.J. Littlewood, J.E. Ironside, D. Rollinson & D. Bou";
2314
        DateTime start = DateTime.now();
2315
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2316
        DateTime end = DateTime.now();
2317
        Duration duration = new Duration(start, end);
2318
        long seconds = duration.getStandardSeconds();
2319
        //this is the critical part of the test that must not be changed
2320
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2321
        //the following may be discussed
2322
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2323

    
2324

    
2325
        //with reference
2326
        nameStr = "Dictyocoela berillonum R.S. Terry, J.E. Sm., R.G. Sharpe, T. Rigaud, D.T.J. Littlewood, J.E. Ironside, D. Rollinson & D. Bou in Species Fauna Atlantica Of Blues Animals 3: p.345. 1758.";
2327
        start = DateTime.now();
2328
        name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2329
        end = DateTime.now();
2330
        duration = new Duration(start, end);
2331
        seconds = duration.getStandardSeconds();
2332
        //this is the critical part of the test that must not be changed
2333
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2334
        //the following may be discussed
2335
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2336
    }
2337

    
2338
    @Test  //#5072
2339
    public final void testLongRunningParsingAuthors(){
2340
        //http://www.regular-expressions.info/catastrophic.html
2341
        //
2342
        //Länge des Nachnamens macht keinen Unterschied
2343
        //Anzahl der "AuthorParts scheint entscheidend
2344
        // & am Ende macht es langsamger (16s), als nur ","(6s))
2345

    
2346
        String authorStr = "R.S. Terry J.E. Sm. R.G. Sharpe T. Rigaud T.H. Rigseaud D.T. Li, R.G. Sharpe, T. Rigaud, D.T.J. Littlewood & D. Bou";
2347
        TeamOrPersonBase[] authorArray = new TeamOrPersonBase[4];
2348
        try {
2349
            DateTime start = DateTime.now();
2350
            parser.fullAuthors(authorStr, authorArray, new Integer[]{1800, null, null, null}, NomenclaturalCode.ICNAFP);
2351
            DateTime end = DateTime.now();
2352
            Duration duration = new Duration(start, end);
2353
            long seconds = duration.getStandardSeconds();
2354
//            System.out.println(seconds);
2355
            //this is the critical part of the test that must not be changed
2356
            Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2357
        } catch (StringNotParsableException e) {
2358
            e.printStackTrace();
2359
            Assert.fail("Authors should be parsable");
2360
        }
2361
    }
2362

    
2363
    /**
2364
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#AuthorshipAndEx(java.lang.String)}.
2365
     */
2366
    @Test
2367
    public final void testAuthorshipAndEx() {
2368
        logger.warn("Not yet implemented"); // TODO
2369
    }
2370

    
2371
    /**
2372
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#Authorship(java.lang.String)}.
2373
     */
2374
    @Test
2375
    public final void testAuthorship() {
2376
        logger.warn("Not yet implemented"); // TODO
2377
    }
2378

    
2379
    @Test
2380
    public final void testParseCultivar() {
2381

    
2382
        TaxonName name;
2383
        String cultivar;
2384

    
2385
        //ICN name is not (yet?) converted to ICNCP name
2386
        name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
2387
        name.setGenusOrUninomial("Pinus");
2388
        name.setSpecificEpithet("beta");
2389
        cultivar = "Abies alba 'Albus'";
2390
        parser.parseReferencedName(name, cultivar, null, true);
2391
        Assert.assertEquals("Changing the code automatically is not implemented needs discussion of wanted", NomenclaturalCode.ICNAFP, name.getNameType());
2392
        Assert.assertTrue(name.isProtectedTitleCache());
2393

    
2394
        //cultivar
2395
        cultivar = "Abies 'Albus'";
2396
        name = (TaxonName)parser.parseFullName(cultivar);
2397
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2398
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2399
        Assert.assertEquals("Abies 'Albus'", name.getNameCache());
2400
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2401

    
2402
        //same but using ...referencedName
2403
        cultivar = "Abies 'Albus'";
2404
        name = parser.parseReferencedName(cultivar);
2405
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2406
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2407
        Assert.assertEquals("Abies 'Albus'", name.getNameCache());
2408
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2409

    
2410
        //cultivar with author
2411
        cultivar = "Abies 'Albus' Mill.";
2412
        name = (TaxonName)parser.parseFullName(cultivar);
2413
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2414
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2415
        Assert.assertEquals("Abies 'Albus'", name.getNameCache());
2416
        Assert.assertNotNull(name.getCombinationAuthorship());
2417
        Assert.assertEquals("Mill.", name.getCombinationAuthorship().getTitleCache());
2418
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2419

    
2420
        //same with referenced name
2421
        cultivar = "Abies 'Albus' Mill.";
2422
        name = parser.parseReferencedName(cultivar);
2423
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2424
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2425
        Assert.assertEquals("Abies 'Albus'", name.getNameCache());
2426
        Assert.assertNotNull(name.getCombinationAuthorship());
2427
        Assert.assertEquals("Mill.", name.getCombinationAuthorship().getTitleCache());
2428
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2429

    
2430
        //cultivar with author and incorrect basionym or ex author
2431
        cultivar = "Abies 'Albus' (Basio) Mill.";
2432
        name = (TaxonName)parser.parseFullName(cultivar);
2433
        Assert.assertTrue("Cultivar name should not have a basionym author", name.isProtectedTitleCache());
2434
        cultivar = "Abies 'Albus' Mill. ex Meyer";
2435
        name = (TaxonName)parser.parseFullName(cultivar);
2436
        Assert.assertTrue("Cultivar name should not have an ex-author", name.isProtectedTitleCache());
2437

    
2438
        //cultivar with author and nom. ref.
2439
        cultivar = "Abies 'Albus' Mill. in Willdenovia 2: 23. 1983";
2440
        name = parser.parseReferencedName(cultivar);
2441
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2442
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2443
        Assert.assertEquals("Abies 'Albus'", name.getNameCache());
2444
        Assert.assertNotNull(name.getCombinationAuthorship());
2445
        Assert.assertEquals("Mill.", name.getCombinationAuthorship().getTitleCache());
2446
        Assert.assertNotNull(name.getNomenclaturalReference());
2447
        Assert.assertEquals("Mill. 1983: \u2013 Willdenovia 2", name.getNomenclaturalReference().getTitleCache());
2448
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2449

    
2450
        cultivar = "Abies 'Beryl, Viscountess Cowdray'";
2451
        name = (TaxonName)parser.parseFullName(cultivar);
2452
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2453
        Assert.assertEquals("Beryl, Viscountess Cowdray", name.getCultivarEpithet());
2454
        Assert.assertEquals("Abies 'Beryl, Viscountess Cowdray'", name.getNameCache());
2455
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2456

    
2457
        cultivar = "Abies 'Jeanne d\u2019Arc'";
2458
        name = (TaxonName)parser.parseFullName(cultivar);
2459
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2460
        Assert.assertEquals("Jeanne d\u2019Arc", name.getCultivarEpithet());
2461
        Assert.assertEquals("Abies 'Jeanne d\u2019Arc'", name.getNameCache());
2462
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2463

    
2464
        cultivar = "Abies 'Oh Boy!'";
2465
        name = (TaxonName)parser.parseFullName(cultivar);
2466
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2467
        Assert.assertEquals("Oh Boy!", name.getCultivarEpithet());
2468
        Assert.assertEquals("Abies 'Oh Boy!'", name.getNameCache());
2469
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2470

    
2471
        cultivar = "Abies 'E.A. Bowles'";
2472
        name = (TaxonName)parser.parseFullName(cultivar);
2473
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2474
        Assert.assertEquals("E.A. Bowles", name.getCultivarEpithet());
2475
        Assert.assertEquals("Abies 'E.A. Bowles'", name.getNameCache());
2476
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2477

    
2478
        cultivar = "Abies 'ENT/100'";
2479
        name = (TaxonName)parser.parseFullName(cultivar);
2480
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2481
        Assert.assertEquals("ENT/100", name.getCultivarEpithet());
2482
        Assert.assertEquals("Abies 'ENT/100'", name.getNameCache());
2483
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2484

    
2485
        cultivar = "Abies 'Go-go  Dancer'";
2486
        name = (TaxonName)parser.parseFullName(cultivar);
2487
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2488
        Assert.assertEquals("Go-go Dancer", name.getCultivarEpithet());
2489
        Assert.assertEquals("Abies 'Go-go Dancer'", name.getNameCache());
2490
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2491

    
2492
        cultivar = "Abies 'ENT\\100'";
2493
        name = (TaxonName)parser.parseFullName(cultivar);
2494
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2495
        Assert.assertEquals("ENT\\100", name.getCultivarEpithet());
2496
        Assert.assertEquals("Abies 'ENT\\100'", name.getNameCache());
2497
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2498

    
2499
        cultivar = "Abies alba 'Albus'";
2500
        name = (TaxonName)parser.parseFullName(cultivar);
2501
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2502
        Assert.assertEquals("alba", name.getSpecificEpithet());
2503
        Assert.assertEquals("Albus", name.getCultivarEpithet());
2504
        Assert.assertEquals("Abies alba 'Albus'", name.getNameCache());
2505
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2506

    
2507
        //cultivar group
2508
        String group = "Abies Albus Group";
2509
        name = (TaxonName)parser.parseFullName(group);
2510
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2511
        Assert.assertNull(name.getSpecificEpithet());
2512
        Assert.assertEquals("Albus Group", name.getCultivarGroupEpithet());
2513
        Assert.assertEquals("Abies Albus Group", name.getNameCache());
2514
        Assert.assertEquals(Rank.uuidCultivarGroup, name.getRank().getUuid());
2515

    
2516
        //same but using referenced name
2517
        group = "Abies Albus Group";
2518
        name = parser.parseReferencedName(group);
2519
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2520
        Assert.assertNull(name.getSpecificEpithet());
2521
        Assert.assertEquals("Albus Group", name.getCultivarGroupEpithet());
2522
        Assert.assertEquals("Abies Albus Group", name.getNameCache());
2523
        Assert.assertEquals(Rank.uuidCultivarGroup, name.getRank().getUuid());
2524

    
2525
        group = "Abies Albus Gp";
2526
        name = (TaxonName)parser.parseFullName(group);
2527
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2528
        Assert.assertNull(name.getSpecificEpithet());
2529
        Assert.assertEquals("Albus Gp", name.getCultivarGroupEpithet());
2530
        Assert.assertEquals("Abies Albus Gp", name.getNameCache());
2531
        Assert.assertEquals(Rank.uuidCultivarGroup, name.getRank().getUuid());
2532

    
2533
        group = "Abies Gruppo Albus";
2534
        name = (TaxonName)parser.parseFullName(group);
2535
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2536
        Assert.assertNull(name.getSpecificEpithet());
2537
        Assert.assertEquals("Gruppo Albus", name.getCultivarGroupEpithet());
2538
        Assert.assertEquals("Abies Gruppo Albus", name.getNameCache());
2539
        Assert.assertEquals(Rank.uuidCultivarGroup, name.getRank().getUuid());
2540

    
2541
        //grex
2542
        String grex = "Abies Albus grex";
2543
        name = (TaxonName)parser.parseFullName(grex);
2544
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2545
        Assert.assertNull(name.getSpecificEpithet());
2546
        Assert.assertEquals("Albus grex", name.getCultivarGroupEpithet());
2547
        Assert.assertEquals("Abies Albus grex", name.getNameCache());
2548
        Assert.assertEquals(Rank.uuidGrexICNCP, name.getRank().getUuid());
2549

    
2550
        //same but using referenced name
2551
        grex = "Abies Albus grex";
2552
        name = parser.parseReferencedName(grex);
2553
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2554
        Assert.assertNull(name.getSpecificEpithet());
2555
        Assert.assertEquals("Albus grex", name.getCultivarGroupEpithet());
2556
        Assert.assertEquals("Abies Albus grex", name.getNameCache());
2557
        Assert.assertEquals(Rank.uuidGrexICNCP, name.getRank().getUuid());
2558

    
2559
        grex = "Abies Albus Second grex";
2560
        name = parser.parseReferencedName(grex);
2561
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2562
        Assert.assertNull(name.getSpecificEpithet());
2563
        Assert.assertEquals("Albus Second grex", name.getCultivarGroupEpithet());
2564
        Assert.assertEquals("Abies Albus Second grex", name.getNameCache());
2565
        Assert.assertEquals(Rank.uuidGrexICNCP, name.getRank().getUuid());
2566

    
2567
        //combined
2568
        String combined = "Abies (Albus Gruppo) 'Pretty'";
2569
        name = parser.parseReferencedName(combined);
2570
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2571
        Assert.assertNull(name.getSpecificEpithet());
2572
        Assert.assertEquals("Pretty", name.getCultivarEpithet());
2573
        Assert.assertEquals("Albus Gruppo", name.getCultivarGroupEpithet());
2574
        Assert.assertEquals(combined, name.getNameCache());
2575
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2576

    
2577
        combined = "Abies White grex (Albus Gruppo) 'Pretty'";
2578
        name = parser.parseReferencedName(combined);
2579
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2580
        Assert.assertNull(name.getSpecificEpithet());
2581
        Assert.assertEquals("Pretty", name.getCultivarEpithet());
2582
        Assert.assertEquals("White grex Albus Gruppo", name.getCultivarGroupEpithet());
2583
        Assert.assertEquals(combined, name.getNameCache());
2584
        Assert.assertEquals(Rank.uuidCultivar, name.getRank().getUuid());
2585

    
2586
        combined = "Abies White grex Albus Gruppo";
2587
        name = parser.parseReferencedName(combined);
2588
        Assert.assertEquals("Abies", name.getGenusOrUninomial());
2589
        Assert.assertNull(name.getSpecificEpithet());
2590
        Assert.assertEquals("White grex Albus Gruppo", name.getCultivarGroupEpithet());
2591
        Assert.assertEquals(combined, name.getNameCache());
2592
        Assert.assertEquals(Rank.uuidCultivarGroup, name.getRank().getUuid());
2593

    
2594
        //incorrect combinations
2595
        combined = "Abies White grex (Albus Gruppo)";
2596
        name = parser.parseReferencedName(combined);
2597
        Assert.assertTrue(name.isProtectedTitleCache());
2598
        Assert.assertNull(name.getGenusOrUninomial());
2599
        Assert.assertNull(name.getSpecificEpithet());
2600
        Assert.assertNull(name.getCultivarEpithet());
2601
        Assert.assertNull(name.getCultivarGroupEpithet());
2602
        Assert.assertEquals(combined, name.getNameCache());
2603
        Assert.assertNull(name.getRank());
2604

    
2605
        combined = "Abies Albus Gruppo 'Pretty'";
2606
        name = parser.parseReferencedName(combined);
2607
        Assert.assertTrue(name.isProtectedTitleCache());
2608
        Assert.assertNull(name.getGenusOrUninomial());
2609
        Assert.assertNull(name.getSpecificEpithet());
2610
        Assert.assertNull(name.getCultivarEpithet());
2611
        Assert.assertNull(name.getCultivarGroupEpithet());
2612
        Assert.assertEquals(combined, name.getNameCache());
2613
        Assert.assertNull(name.getRank());
2614
    }
2615

    
2616
    @Test
2617
    public final void testNomenclaturalStatus() {
2618
        IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY(), "Acanthopale", null, null, null, null, null, null, null);
2619
        name.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ALTERNATIVE()));
2620
        IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
2621
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2622
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2623
        Assert.assertEquals("Title cache should be same. No duplication of nom. status should take place", name.getFullTitleCache(), name2.getFullTitleCache());
2624
    }
2625

    
2626
    @Test
2627
    public final void testSpecificAuthors(){
2628
        //McVaugh
2629
        INonViralName name = parser.parseFullName("Psidium longipes var. orbiculare (O.Berg) McVaugh");
2630
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2631
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2632
        assertEquals( "McVaugh", combinationAuthor.getNomenclaturalTitleCache());
2633
        TeamOrPersonBase<?> basionymAuthor = name.getBasionymAuthorship();
2634
        assertEquals( "O.Berg", basionymAuthor.getNomenclaturalTitleCache());
2635

    
2636
//      Campanula rhodensis A. DC.
2637

    
2638
    }
2639

    
2640
    @Test
2641
    public final void testBookSectionAuthors(){
2642
        INonViralName name;
2643
        Reference nomRef;
2644
        String title;
2645
        String str;
2646

    
2647
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2648
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2649
        name = parser.parseReferencedName(str);
2650
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2651
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2652
        assertEquals( "Asch. & Schweinf.", combinationAuthor.getNomenclaturalTitleCache());
2653
        nomRef = name.getNomenclaturalReference();
2654
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2655
        assertEquals( "Barbey-Boissier & Barbey", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2656
        title = nomRef.getInReference().getAbbrevTitle();
2657
        assertEquals( "Herb. Levant", title);
2658

    
2659
        name = parser.parseReferencedName("Luzula multiflora subsp. pallescens (Sw.) Reichg. in Van Ooststroom & al., Fl. Neerl. 1: 208. 1964");
2660
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2661
        assertEquals( "Reichg.", name.getCombinationAuthorship().getNomenclaturalTitleCache());
2662
        nomRef = name.getNomenclaturalReference();
2663
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2664
        assertEquals( "Van Ooststroom & al.", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2665
        title = nomRef.getInReference().getAbbrevTitle();
2666
        assertEquals( "Fl. Neerl.", title);
2667

    
2668
        str = "Salvia pratensis var. albiflora T. Durand in De Wildeman & Durand, Prodr. Fl. Belg. 3: 663. 1899";
2669
        name = parser.parseReferencedName(str);
2670
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2671
        assertEquals( "T. Durand", name.getCombinationAuthorship().getNomenclaturalTitleCache());
2672
        nomRef = name.getNomenclaturalReference();
2673
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2674
        assertEquals( "De Wildeman & Durand", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2675
        title = nomRef.getInReference().getAbbrevTitle();
2676
        assertEquals( "Prodr. Fl. Belg.", title);
2677

    
2678
        str = "Bravoa Lex. in La Llave & Lexarza, Nov. Veg. Desc. 1: 6. 1824";
2679
        name = parser.parseReferencedName(str);
2680
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2681
        assertEquals( "Lex.", name.getCombinationAuthorship().getNomenclaturalTitleCache());
2682
        nomRef = name.getNomenclaturalReference();
2683
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2684
        assertEquals( "La Llave & Lexarza", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2685
        title = nomRef.getInReference().getAbbrevTitle();
2686
        assertEquals( "Nov. Veg. Desc.", title);
2687

    
2688
        str = "Thymus trachselianus var. vallicola Heinr. Braun in Dalla Torre & Sarnthein, Fl. Tirol 6(3): 204. 1912";
2689
        name = parser.parseReferencedName(str);
2690
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2691
        nomRef = name.getNomenclaturalReference();
2692
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2693
        assertEquals( "Dalla Torre & Sarnthein", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2694
        title = nomRef.getInReference().getAbbrevTitle();
2695
        assertEquals( "Fl. Tirol", title);
2696

    
2697
        //see #openIssues
2698
//        str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2699
//        name = parser.parseReferencedName(str);
2700
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2701
//        nomRef = name.getNomenclaturalReference();
2702
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2703
//        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2704
//        title = nomRef.getInReference().getAbbrevTitle();
2705
//        assertEquals( "Nova Fl. Portugal", title);
2706
//
2707
//        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2708
//        name = parser.parseReferencedName(str);
2709
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2710
//        nomRef = name.getNomenclaturalReference();
2711
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2712
//        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
2713
//        title = nomRef.getInReference().getAbbrevTitle();
2714
//        assertEquals( "Mount. Fl. Greece", title);
2715

    
2716
    }
2717

    
2718
    @Test
2719
    public final void testDatePublished(){
2720

    
2721
        INonViralName name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. 1977 publ. 1978");
2722
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2723
        Reference nomRef = name.getNomenclaturalReference();
2724
        assertEquals(ReferenceType.Article, nomRef.getType());
2725
        assertEquals("1978 [\"1977\"]", nomRef.getDatePublished().toString());
2726

    
2727
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. 4 Apr 1977");
2728
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2729
        nomRef = name.getNomenclaturalReference();
2730
        assertEquals(ReferenceType.Article, nomRef.getType());
2731
        assertEquals("4 Apr 1977", nomRef.getDatePublished().toString());
2732
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getStartMonth());
2733

    
2734
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. Feb-Apr 1977");
2735
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2736
        nomRef = name.getNomenclaturalReference();
2737
        assertEquals(ReferenceType.Article, nomRef.getType());
2738
        assertEquals("Feb"+SEP+"Apr 1977", nomRef.getDatePublished().toString());
2739
        assertEquals(Integer.valueOf(2), nomRef.getDatePublished().getStartMonth());
2740
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getEndMonth());
2741
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getStartYear());
2742
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getEndYear());
2743
        assertNull(nomRef.getDatePublished().getStartDay());
2744
        assertNull(nomRef.getDatePublished().getEndDay());
2745
    }
2746

    
2747

    
2748
    @Test
2749
    public final void testExistingProblems(){
2750

    
2751
        INonViralName name;
2752
        String str = "Cerastium nutans var. occidentale Boivin in Canad. Field-Naturalist 65: 5. 1951";
2753
        name = parser.parseReferencedName(str);
2754
        Assert.assertTrue(isParsable(str, NomenclaturalCode.ICNAFP));
2755

    
2756
        //Canabio, issue with space
2757
        name = parser.parseReferencedName("Machaonia erythrocarpa var. hondurensis (Standl.) Borhidi"
2758
                + " in Acta Bot. Hung. 46 (1-2): 30. 2004");
2759
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2760
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2761
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitleCache());
2762
        Reference nomRef = name.getNomenclaturalReference();
2763
        assertEquals(ReferenceType.Article, nomRef.getType());
2764
        assertEquals("46 (1-2)", nomRef.getVolume());
2765

    
2766
        //Canabio, detail with fig.
2767
        name = parser.parseReferencedName("Didymaea floribunda Rzed."
2768
                + " in Bol. Soc. Bot. Mex. 44: 72, fig. 1. 1983");
2769
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2770
        combinationAuthor = name.getCombinationAuthorship();
2771
        assertEquals( "Rzed.", combinationAuthor.getNomenclaturalTitleCache());
2772
        nomRef = name.getNomenclaturalReference();
2773
        assertEquals(ReferenceType.Article, nomRef.getType());
2774
        assertEquals("44", nomRef.getVolume());
2775
        assertEquals("72, fig. 1", name.getNomenclaturalMicroReference());
2776

    
2777
        //fig with a-c and without dot
2778
        name = parser.parseReferencedName("Deppea guerrerensis Dwyer & Lorence"
2779
                + " in Allertonia 4: 428. fig 4a-c. 1988");  //
2780
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2781
        combinationAuthor = name.getCombinationAuthorship();
2782
        assertEquals( "Dwyer & Lorence", combinationAuthor.getNomenclaturalTitleCache());
2783
        nomRef = name.getNomenclaturalReference();
2784
        assertEquals(ReferenceType.Article, nomRef.getType());
2785
        assertEquals("4", nomRef.getVolume());
2786
        assertEquals("428. fig 4a-c", name.getNomenclaturalMicroReference());
2787

    
2788
        //issue with EN_DASH (3–4)
2789
        name = parser.parseReferencedName("Arachnothryx tacanensis (Lundell) Borhidi"
2790
              + " in Acta Bot. Hung. 33 (3" + UTF8.EN_DASH + "4): 303. 1987");
2791
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2792
        combinationAuthor = name.getCombinationAuthorship();
2793
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitleCache());
2794
        nomRef = name.getNomenclaturalReference();
2795
        assertEquals(ReferenceType.Article, nomRef.getType());
2796
        assertEquals("33 (3" + UTF8.EN_DASH + "4)", nomRef.getVolume());
2797
        assertEquals("303", name.getNomenclaturalMicroReference());
2798

    
2799
        //fig with f.
2800
        name = parser.parseReferencedName("Stenotis Terrell"
2801
                + " in Sida 19(4): 901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2. 2001");
2802
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2803
        combinationAuthor = name.getCombinationAuthorship();
2804
        assertEquals( "Terrell", combinationAuthor.getNomenclaturalTitleCache());
2805
        nomRef = name.getNomenclaturalReference();
2806
        assertEquals(ReferenceType.Article, nomRef.getType());
2807
        assertEquals("19(4)", nomRef.getVolume());
2808
        assertEquals("901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2", name.getNomenclaturalMicroReference());
2809

    
2810
        //detail with figs
2811
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2812
                + " in Contr. Dudley Herb. 3: 75, figs 4-6. 1940");
2813
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2814
        combinationAuthor = name.getCombinationAuthorship();
2815
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitleCache());
2816
        nomRef = name.getNomenclaturalReference();
2817
        assertEquals(ReferenceType.Article, nomRef.getType());
2818
        assertEquals("3", nomRef.getVolume());
2819
        assertEquals("75, figs 4-6", name.getNomenclaturalMicroReference());
2820

    
2821
        //detail with pl. and figs
2822
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2823
                + " in Contr. Dudley Herb. 3: 75, pl. 19, figs 4-6. 1940");
2824
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2825
        combinationAuthor = name.getCombinationAuthorship();
2826
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitleCache());
2827
        nomRef = name.getNomenclaturalReference();
2828
        assertEquals(ReferenceType.Article, nomRef.getType());
2829
        assertEquals("3", nomRef.getVolume());
2830
        assertEquals("75, pl. 19, figs 4-6", name.getNomenclaturalMicroReference());
2831

    
2832
        //pl
2833
        name = parser.parseReferencedName("Carapichea  Aubl."
2834
                + " in Hist. Pl. Guiane 1: 167, pl. 64. 1775");
2835
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2836
        combinationAuthor = name.getCombinationAuthorship();
2837
        assertEquals( "Aubl.", combinationAuthor.getNomenclaturalTitleCache());
2838
        nomRef = name.getNomenclaturalReference();
2839
        assertEquals(ReferenceType.Article, nomRef.getType());
2840
        assertEquals("1", nomRef.getVolume());
2841
        assertEquals("167, pl. 64", name.getNomenclaturalMicroReference());
2842

    
2843
        //fig with ,
2844
        name = parser.parseReferencedName("Hoffmannia ixtlanensis Lorence"
2845
                + " in Novon 4: 121. fig. 2a, b. 1994");
2846
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2847
        combinationAuthor = name.getCombinationAuthorship();
2848
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitleCache());
2849
        nomRef = name.getNomenclaturalReference();
2850
        assertEquals(ReferenceType.Article, nomRef.getType());
2851
        assertEquals("4", nomRef.getVolume());
2852
        assertEquals("121. fig. 2a, b", name.getNomenclaturalMicroReference());
2853

    
2854
        //detail with , to number
2855
        name = parser.parseReferencedName("Deppea martinez-calderonii Lorence"
2856
                + " in Allertonia 4: 399. figs 1e, 2. 1988");
2857
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2858
        combinationAuthor = name.getCombinationAuthorship();
2859
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitleCache());
2860
        nomRef = name.getNomenclaturalReference();
2861
        assertEquals(ReferenceType.Article, nomRef.getType());
2862
        assertEquals("4", nomRef.getVolume());
2863
        assertEquals("399. figs 1e, 2", name.getNomenclaturalMicroReference());
2864

    
2865
        //(Suppl.)
2866
        name = parser.parseReferencedName("Manettia costaricensis  Wernham"
2867
                + " in J. Bot. 57(Suppl.): 38. 1919");
2868
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2869
        combinationAuthor = name.getCombinationAuthorship();
2870
        assertEquals( "Wernham", combinationAuthor.getNomenclaturalTitleCache());
2871
        nomRef = name.getNomenclaturalReference();
2872
        assertEquals(ReferenceType.Article, nomRef.getType());
2873
        assertEquals("57(Suppl.)", nomRef.getVolume());
2874
        assertEquals("38", name.getNomenclaturalMicroReference());
2875

    
2876
        //NY.
2877
        name = parser.parseReferencedName("Crusea psyllioides (Kunth) W.R. Anderson"
2878
                + " in Mem. NY. Bot. Gard. 22: 75. 1972");
2879
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2880
        combinationAuthor = name.getCombinationAuthorship();
2881
        assertEquals( "W.R. Anderson", combinationAuthor.getNomenclaturalTitleCache());
2882
        nomRef = name.getNomenclaturalReference();
2883
        assertEquals(ReferenceType.Article, nomRef.getType());
2884
        assertEquals("22", nomRef.getVolume());
2885
        assertEquals("75", name.getNomenclaturalMicroReference());
2886

    
2887
        //apostroph word in title
2888
        name = parser.parseReferencedName("Sabicea glabrescens Benth."
2889
                + " in Hooker's J. Bot. Kew Gard. Misc. 3: 219. 1841");
2890
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2891
        combinationAuthor = name.getCombinationAuthorship();
2892
        assertEquals( "Benth.", combinationAuthor.getNomenclaturalTitleCache());
2893
        nomRef = name.getNomenclaturalReference();
2894
        assertEquals(ReferenceType.Article, nomRef.getType());
2895
        assertEquals("3", nomRef.getVolume());
2896
        assertEquals("219", name.getNomenclaturalMicroReference());
2897

    
2898
        // place published e.g. (Hannover)
2899
        name = parser.parseReferencedName("Pittoniotis trichantha Griseb."
2900
                  + " in Bonplandia (Hannover) 6 (1): 8. 1858");
2901
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2902
        combinationAuthor = name.getCombinationAuthorship();
2903
        assertEquals( "Griseb.", combinationAuthor.getNomenclaturalTitleCache());
2904
        nomRef = name.getNomenclaturalReference();
2905
        assertEquals(ReferenceType.Article, nomRef.getType());
2906
        assertEquals("6 (1)", nomRef.getVolume());
2907
        assertEquals("8", name.getNomenclaturalMicroReference());
2908

    
2909
        //komplex / incorrect year without quotation marks
2910
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2911
                + " in Acta Bot. Hung. 29(1\u20134): 16, f. 1\u20132, t. 1-8. 1983 [1984]");
2912
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2913
        combinationAuthor = name.getCombinationAuthorship();
2914
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitleCache());
2915
        nomRef = name.getNomenclaturalReference();
2916
        assertEquals(ReferenceType.Article, nomRef.getType());
2917
        assertEquals("29(1\u20134)", nomRef.getVolume());
2918
        assertEquals("16, f. 1\u20132, t. 1-8", name.getNomenclaturalMicroReference());
2919
        assertEquals("1983 [1984]", nomRef.getDatePublishedString());
2920
//        assertEquals("1984", nomRef.getYear()); //was like this, but is not necessarily correct, see #7429
2921

    
2922
        //incorrect year with \u201e \u201f  (s. eu.etaxonomy.cdm.common.UTF8.ENGLISH_QUOT_START
2923
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2924
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \u201e1983\u201f [1984]");
2925
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2926
        combinationAuthor = name.getCombinationAuthorship();
2927
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitleCache());
2928
        nomRef = name.getNomenclaturalReference();
2929
        assertEquals(ReferenceType.Article, nomRef.getType());
2930
        assertEquals("29(1-4)", nomRef.getVolume());
2931
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2932
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2933
        assertEquals("1984", nomRef.getYear());
2934

    
2935
        //incorrect year with "
2936
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2937
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \"1983\" [1984]");
2938
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2939
        combinationAuthor = name.getCombinationAuthorship();
2940
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitleCache());
2941
        nomRef = name.getNomenclaturalReference();
2942
        assertEquals(ReferenceType.Article, nomRef.getType());
2943
        assertEquals("29(1-4)", nomRef.getVolume());
2944
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2945
        //changed from "1983" [1984] to 1984 ["1983"] after implementing #7429
2946
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2947
        assertEquals("1984", nomRef.getYear());
2948

    
2949
        //fig. a
2950
        name = parser.parseReferencedName("Psychotria capitata  Ruiz & Pav."
2951
                + " in Fl. Peruv. 2: 59, pl. 206, fig. a. 1799");
2952
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2953
        combinationAuthor = name.getCombinationAuthorship();
2954
        assertEquals( "Ruiz & Pav.", combinationAuthor.getNomenclaturalTitleCache());
2955
        nomRef = name.getNomenclaturalReference();
2956
        assertEquals(ReferenceType.Article, nomRef.getType());
2957
        assertEquals("2", nomRef.getVolume());
2958
        assertEquals("59, pl. 206, fig. a", name.getNomenclaturalMicroReference());
2959

    
2960
        //442A.
2961
        name = parser.parseReferencedName("Rogiera elegans Planch."
2962
                + " in Fl. Serres Jard. Eur. 5: 442A. 1849");
2963
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2964
        combinationAuthor = name.getCombinationAuthorship();
2965
        assertEquals( "Planch.", combinationAuthor.getNomenclaturalTitleCache());
2966
        nomRef = name.getNomenclaturalReference();
2967
        assertEquals(ReferenceType.Article, nomRef.getType());
2968
        assertEquals("5", nomRef.getVolume());
2969
        assertEquals("442A", name.getNomenclaturalMicroReference());
2970

    
2971
        //f
2972
        name = parser.parseReferencedName("Coussarea imitans L.O. Williams"
2973
                + " in Phytologia 26 (6): 488-489, f. 1973");
2974
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2975
        combinationAuthor = name.getCombinationAuthorship();
2976
        assertEquals( "L.O. Williams", combinationAuthor.getNomenclaturalTitleCache());
2977
        nomRef = name.getNomenclaturalReference();
2978
        assertEquals(ReferenceType.Article, nomRef.getType());
2979
        assertEquals("26 (6)", nomRef.getVolume());
2980
        assertEquals("488-489, f", name.getNomenclaturalMicroReference());
2981

    
2982
        //Phys.-Med.
2983
        name = parser.parseReferencedName("Coccocypselum cordifolium Nees & Mart."
2984
                + " in Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur. 12: 14. 1824");
2985
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2986
        combinationAuthor = name.getCombinationAuthorship();
2987
        assertEquals( "Nees & Mart.", combinationAuthor.getNomenclaturalTitleCache());
2988
        nomRef = name.getNomenclaturalReference();
2989
        assertEquals(ReferenceType.Article, nomRef.getType());
2990
        assertEquals("Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur.", nomRef.getInReference().getAbbrevTitle());
2991
        assertEquals("12", nomRef.getVolume());
2992
        assertEquals("14", name.getNomenclaturalMicroReference());
2993
        assertEquals("1824", nomRef.getYear());
2994

    
2995
        //(ed. 10)  wanted?
2996
//        Syst. Nat. (ed. 10) 2: 930. 1759
2997
//        name = parser.parseReferencedName("Erithalis fruticosa L."
2998
//                + ", Syst. Nat. ed. 10, 2: 930. 1759");
2999
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3000
//        combinationAuthor = name.getCombinationAuthorship();
3001
//        assertEquals( "L.", combinationAuthor.getNomenclaturalTitleCache());
3002
//        nomRef = (Reference)name.getNomenclaturalReference();
3003
//        assertEquals(ReferenceType.Book, nomRef.getType());
3004
//        assertEquals("2", nomRef.getVolume());
3005
//        assertEquals("10", nomRef.getEdition());
3006
//        assertEquals("930", name.getNomenclaturalMicroReference());
3007
//        assertEquals("1759", nomRef.getYear());
3008

    
3009
        //issue with letter "(1a)"
3010
        name = parser.parseReferencedName("Arthraerua (Kuntze) Schinz,"
3011
                + " Nat. Pflanzenfam. 3(1a): 109. 1893");
3012
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3013
        combinationAuthor = name.getCombinationAuthorship();
3014
        assertEquals( "Schinz", combinationAuthor.getNomenclaturalTitleCache());
3015
        nomRef = name.getNomenclaturalReference();
3016
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
3017
        assertEquals(ReferenceType.Book, nomRef.getType());
3018
        assertEquals("Nat. Pflanzenfam.", nomRef.getAbbrevTitle());
3019
        assertEquals("3(1a)", nomRef.getVolume());
3020
        assertEquals("109", name.getNomenclaturalMicroReference());
3021
        assertEquals("1893", nomRef.getYear());
3022

    
3023
        //Accent graph in author name #6057
3024
        name = parser.parseReferencedName("Sedum plicatum O`Brian");
3025
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3026
        assertEquals( "O`Brian", name.getCombinationAuthorship().getNomenclaturalTitleCache());
3027

    
3028
        //-e-  #6060
3029
        name = parser.parseReferencedName("Thamniopsis stenodictyon (Sehnem) Oliveira-e-Silva & O.Yano");
3030
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3031
        Team team = (Team)name.getCombinationAuthorship();
3032
        assertEquals( "Oliveira-e-Silva", team.getTeamMembers().get(0).getNomenclaturalTitleCache());
3033

    
3034
        //Vorabdr.
3035
        name = parser.parseReferencedName("Ophrys hystera  Kreutz & Ruedi Peter in J. Eur. Orchideen 30(Vorabdr.): 128. 1997");
3036
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3037
        assertEquals( "30(Vorabdr.)", name.getNomenclaturalReference().getVolume());
3038

    
3039
        //#6100  jun.
3040
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
3041
        name = parser.parseFullName(nameStr, botanicCode, null);  //fails with missing botanicCode, see open issues
3042
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3043
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
3044

    
3045
        //#6100 bis /ter
3046
        nameStr = "Schistidium aquaticum (R.Br.ter) Ochyra";
3047
        name = parser.parseFullName(nameStr);
3048
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3049
        assertEquals( "R.Br.ter", name.getBasionymAuthorship().getTitleCache());
3050

    
3051
        nameStr = "Grimmia mitchellii R.Br.bis";
3052
        name = parser.parseFullName(nameStr);
3053
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3054
        assertEquals( "R.Br.bis", name.getCombinationAuthorship().getTitleCache());
3055

    
3056
        //forma #6100
3057
        nameStr = "Xerocomus parasiticus forma piperatoides (J. Blum) R. Mazza";
3058
        name = parser.parseFullName(nameStr);
3059
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3060
        assertEquals( "piperatoides", name.getInfraSpecificEpithet());
3061
        assertEquals( Rank.FORM(), name.getRank());
3062

    
3063
        //subgen. #6100
3064
        nameStr = "Aliciella subgen. Gilmania (H.Mason & A.D.Grant) J.M.Porter";
3065
        name = parser.parseFullName(nameStr);
3066
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3067
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
3068
        assertEquals( Rank.SUBGENUS(), name.getRank());
3069

    
3070
        //subgen. #6100
3071
        nameStr = "Aliciella subgen. Gilmania J.M.Porter";
3072
        name = parser.parseFullName(nameStr);
3073
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3074
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
3075
        assertEquals( Rank.SUBGENUS(), name.getRank());
3076
        assertEquals( "J.M.Porter", name.getCombinationAuthorship().getTitleCache());
3077

    
3078
        //la Croix #6100
3079
        nameStr = "Eulophia ovalis var. bainesii (Rolfe) P.J.Cribb & la Croix";
3080
        name = parser.parseFullName(nameStr);
3081
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3082
        assertEquals( "P.J.Cribb & la Croix", name.getCombinationAuthorship().getTitleCache());
3083

    
3084
        //I = Yi #6100
3085
        nameStr = "Parasenecio hwangshanicus (P.I Mao) C.I Peng";
3086
        name = parser.parseFullName(nameStr);
3087
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3088
        assertEquals("I (=Yi) should be an accepted ending", "C.I Peng", name.getCombinationAuthorship().getTitleCache());
3089
        assertEquals("I (=Yi) should be an accepted ending", "P.I Mao", name.getBasionymAuthorship().getTitleCache());
3090

    
3091
        //´t Hart #6100
3092
        nameStr = "Sedum decipiens (Baker) Thiede & \u00B4t Hart";   //still does not work with "´", don't know what the difference is, see openIssues()
3093
        name = parser.parseFullName(nameStr);
3094
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3095
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
3096
                "Thiede & \u00B4t Hart", name.getCombinationAuthorship().getTitleCache());
3097

    
3098
        //Man in 't Veld  #6100
3099
        nameStr = "Phytophthora multivesiculata Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters";
3100
        name = parser.parseFullName(nameStr);
3101
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3102
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
3103
                name.getCombinationAuthorship().getTitleCache());
3104
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
3105
                name.getCombinationAuthorship().getNomenclaturalTitleCache());
3106

    
3107
        nameStr = "Thymus \u00D7 herberoi De la Torre, Vicedo, Alonso & Paya";
3108
        name = parser.parseFullName(nameStr);
3109
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3110
        //TODO may become ... Alonso & al. again in future
3111
        assertEquals("Thymus \u00D7herberoi De la Torre, Vicedo, Alonso & Paya", name.getTitleCache());
3112
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
3113
                name.getCombinationAuthorship().getTitleCache());
3114
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
3115
                name.getCombinationAuthorship().getNomenclaturalTitleCache());
3116

    
3117
        //Sant'Anna
3118
        nameStr = "Coelosphaerium evidenter-marginatum M.T.P.Azevedo & Sant'Anna";
3119
        name = parser.parseFullName(nameStr);
3120
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3121
        assertEquals("M.T.P.Azevedo & Sant'Anna", name.getCombinationAuthorship().getTitleCache());
3122

    
3123
        //Heft
3124
        nameStr = "Nepenthes deaniana Macfarl. in Engl., Mein Pflanzenr. IV. 111 (Heft 36): 57. 1908.";
3125
        name = parser.parseReferencedName(nameStr);
3126
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3127
        Reference ref = name.getNomenclaturalReference();
3128
        Assert.assertFalse("Reference should be parsable", ref.hasProblem());
3129
        //or even better IV. 111 (Heft 36), but this is currently not implemented
3130
        assertEquals("111 (Heft 36)", ref.getInReference().getVolume());
3131

    
3132
        //journal with commata at pos 4
3133
        nameStr = "Bufonia kotschyana subsp. densa Chrtek & Krisa in Acta Univ.Carol., Biol. 43(2): 105. 1999";
3134
        name = parser.parseReferencedName(nameStr);
3135
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3136
        String author = name.getAuthorshipCache();
3137
        assertEquals("Chrtek & Krisa", author);
3138
        ref = name.getNomenclaturalReference();
3139
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3140
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3141

    
3142
        //Adansonia #9014, #9551
3143
        nameStr = "Casearia annamensis (Gagnep.) Lescot & Sleumer in Adansonia, n.s., 10: 290. 1970";
3144
        name = parser.parseReferencedName(nameStr);
3145
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3146
        ref = name.getNomenclaturalReference();
3147
        Assert.assertEquals(ReferenceType.Article, ref.getType());
3148
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3149
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3150
        Assert.assertEquals("Adansonia", ref.getInReference().getAbbrevTitle());
3151

    
3152
        //, Bot., sér. 4 #9014, #9551
3153
        String ser = "s"+UTF8.SMALL_E_ACUTE+"r";
3154
        nameStr = "Asteropeia amblyocarpa Tul. in Ann. Sci. Nat., Bot., "+ser+". 4, 8: 81. 1857";
3155
        name = parser.parseReferencedName(nameStr);
3156
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3157
        ref = name.getNomenclaturalReference();
3158
        Assert.assertEquals(ReferenceType.Article, ref.getType());
3159
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3160
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3161
        Assert.assertEquals("Ann. Sci. Nat., Bot.", ref.getInReference().getAbbrevTitle());
3162
        Assert.assertEquals(ser+". 4", ref.getSeriesPart());
3163

    
3164
        // Misc. 89   #9014
3165
        nameStr = "Bulbophyllum sordidum Lindl. in Edwards's Bot. Reg. 26: Misc. 89. 1840";
3166
        name = parser.parseReferencedName(nameStr);
3167
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3168
        String detail = name.getNomenclaturalMicroReference();
3169
        Assert.assertEquals("Misc. 89", detail);
3170
        ref = name.getNomenclaturalReference();
3171
        Assert.assertEquals(ReferenceType.Article, ref.getType());
3172
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3173
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3174
        Assert.assertEquals("Edwards's Bot. Reg.", ref.getInReference().getAbbrevTitle());
3175

    
3176
        // #9014 ... in Sitzungsber. Math.-Phys. Cl. Königl. Bayer. Akad. Wiss. München 14: 489. 1884
3177
        nameStr = "Daphnopsis cuneata Radlk. in Sitzungsber. Math.-Phys. Cl. Königl. Bayer. Akad. Wiss. München 14: 489. 1884";
3178
        name = parser.parseReferencedName(nameStr);
3179
        Assert.assertTrue(isParsable(nameStr, ICNAFP));
3180
        Assert.assertEquals("489", name.getNomenclaturalMicroReference());
3181
        ref = name.getNomenclaturalReference();
3182
        Assert.assertEquals(ReferenceType.Article, ref.getType());
3183
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3184
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3185
        Assert.assertEquals("Sitzungsber. Math.-Phys. Cl. Königl. Bayer. Akad. Wiss. München", ref.getInReference().getAbbrevTitle());
3186
        Assert.assertEquals("14", ref.getVolume());
3187

    
3188
    }
3189

    
3190
    @Test
3191
    public final void explicitJournalTitles(){
3192
        //PhytoKeys #9550
3193
        String nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PhytoKeys 137: 68. 2020";
3194
        TaxonName name = parser.parseReferencedName(nameStr);
3195
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3196
        Reference ref = name.getNomenclaturalReference();
3197
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3198
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3199
        Assert.assertEquals("PhytoKeys", ref.getInReference().getAbbrevTitle());
3200

    
3201
        //PLoS ONE #9550 //remaining issue: ", e82692" #9552
3202
//        nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PLoS ONE 8(12), e82692: 17. 2013";
3203
        nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PLoS ONE 8(12): 17. 2013";
3204
        name = parser.parseReferencedName(nameStr);
3205
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3206
        ref = name.getNomenclaturalReference();
3207
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
3208
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
3209
        Assert.assertEquals("PLoS ONE", ref.getInReference().getAbbrevTitle());
3210
    }
3211

    
3212
    @Test
3213
    //#3666
3214
    public final void testOriginalSpelling(){
3215

    
3216
        String nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa\"]";
3217
        TaxonName name = parser.parseReferencedName(nameStr);
3218
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3219
        Reference ref = name.getNomenclaturalReference();
3220
        Assert.assertFalse("Reference should be parsable", ref.isProtectedTitleCache());
3221
        TaxonName originalName = name.getNomenclaturalSource().getNameUsedInSource();
3222
        Assert.assertNotNull("An original spelling should exist", originalName);
3223
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3224
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
3225
        Assert.assertEquals("Sp. Pl.", name.getNomenclaturalSource().getCitation().getAbbrevTitle());
3226
        Assert.assertEquals("1751", name.getNomenclaturalSource().getCitation().getYear());
3227

    
3228
        //without ref
3229
        nameStr = "Abies alba Mill [as \"alpa\"]";
3230
        name = parser.parseReferencedName(nameStr);
3231
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3232
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3233
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
3234

    
3235
        //without author
3236
        nameStr = "Abies alba [as \"alpa\"]";
3237
        name = parser.parseReferencedName(nameStr);
3238
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3239
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3240
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
3241

    
3242
        //with status
3243
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa\"], nom. inval.";
3244
        name = parser.parseReferencedName(nameStr);
3245
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3246
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3247
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
3248
        Assert.assertEquals(1, name.getStatus().size());
3249

    
3250
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Abies alpa\"]";
3251
        name = parser.parseReferencedName(nameStr);
3252
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3253
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3254
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
3255

    
3256
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Apies alpa\"]";
3257
        name = parser.parseReferencedName(nameStr);
3258
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3259
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3260
        Assert.assertEquals("Apies alpa", originalName.getNameCache());
3261

    
3262
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Apies\"]";
3263
        name = parser.parseReferencedName(nameStr);
3264
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3265
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3266
        Assert.assertEquals("Apies alba", originalName.getNameCache());
3267

    
3268
        nameStr = "Abies alba subsp. beta Mill, Sp. Pl. 2: 333. 1751 [as \"peta\"]";
3269
        name = parser.parseReferencedName(nameStr);
3270
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3271
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3272
        Assert.assertEquals("Abies alba subsp. peta", originalName.getNameCache());
3273

    
3274
        nameStr = "Abies alba subsp. beta Mill, Sp. Pl. 2: 333. 1751 [as \"alpa subsp. peta\"]";
3275
        name = parser.parseReferencedName(nameStr);
3276
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
3277
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
3278
        Assert.assertEquals("Abies alpa subsp. peta", originalName.getNameCache());
3279

    
3280
        //unparsable
3281
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa Err\"]";
3282
        Assert.assertTrue("Reference should notbe parsable", parser.parseReferencedName(nameStr).getNomenclaturalReference().isProtectedTitleCache());
3283

    
3284
    }
3285

    
3286
    @Test
3287
    public final void testHort(){
3288
        String nameStr = "Epidendrum ciliare var. minor hort. ex Stein";
3289
        TaxonName name = parser.parseReferencedName(nameStr);
3290
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3291
        Assert.assertEquals("Epidendrum ciliare var. minor", name.getNameCache());
3292
        Assert.assertEquals("hort.", name.getExCombinationAuthorship().getNomenclaturalTitleCache());
3293
        Assert.assertEquals("Stein", name.getCombinationAuthorship().getNomenclaturalTitleCache());
3294
    }
3295

    
3296
    @Test
3297
    @Ignore
3298
    public final void openIssues(){
3299
        //#6100  jun.
3300
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
3301
        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
3302
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3303
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
3304
        name = parser.parseFullName(nameStr);  //fails for some reasons without botanicCode given, as anyBotanicFullName is not recognized, strange because other very similar names such as Thymus \u00D7 herberoi De la Torre, Vicedo, Alonso & Paya do not fail
3305
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3306
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
3307

    
3308
        //´t Hart #6100
3309
        nameStr = "Sedum decipiens (Baker) Thiede & \u00B4t Hart";   //still does not work with "´" if compiled by maven, don't know what the difference is
3310
        name = parser.parseFullName(nameStr);
3311
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3312
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
3313
                "Thiede & \u00B4t Hart", name.getCombinationAuthorship().getTitleCache());
3314
        nameStr = "Sedum decipiens (Baker) Thiede & ´t Hart";   //does not work if compiled with maven
3315
        name = parser.parseFullName(nameStr);
3316
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3317
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
3318
                "Thiede & ´t Hart", name.getCombinationAuthorship().getTitleCache());
3319

    
3320
        //should be recognized as book section (see testBookSectionAuthors)
3321
        String str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
3322
        name = parser.parseReferencedName(str);
3323
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3324
        Reference nomRef = name.getNomenclaturalReference();
3325
        assertEquals(ReferenceType.BookSection, nomRef.getType());
3326
        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
3327
        assertEquals( "Nova Fl. Portugal", nomRef.getInReference().getAbbrevTitle());
3328

    
3329
        //same
3330
        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
3331
        name = parser.parseReferencedName(str);
3332
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3333
        nomRef = name.getNomenclaturalReference();
3334
        assertEquals(ReferenceType.BookSection, nomRef.getType());
3335
        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitleCache());
3336
        assertEquals( "Mount. Fl. Greece", nomRef.getInReference().getAbbrevTitle());
3337
    }
3338

    
3339
    //this is a slot for testing new string, once the Strings tested here work move the according test
3340
    //to one of the above methods (or remove it if not needed)
3341
    @Test
3342
    public final void testNew(){
3343
//        String nameStr = "Eclipta humilis Kunth, Nov. Gen. Sp. Pl. (folio ed.) 4. 1820 [1818]";
3344
//
3345
//        TaxonName name = parser.parseReferencedName(nameStr);
3346
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3347
//        Assert.assertFalse("Name should be parsable", name.isProtectedFullTitleCache());
3348
//        Assert.assertEquals("Eclipta humilis", name.getNameCache());
3349
//        Reference nomRef = name.getNomenclaturalReference();
3350
    }
3351

    
3352
}
(4-4/6)