Project

General

Profile

Download (179 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.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.INomenclaturalAuthor;
33
import eu.etaxonomy.cdm.model.agent.Person;
34
import eu.etaxonomy.cdm.model.agent.Team;
35
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
36
import eu.etaxonomy.cdm.model.common.TimePeriod;
37
import eu.etaxonomy.cdm.model.name.HybridRelationship;
38
import eu.etaxonomy.cdm.model.name.IBotanicalName;
39
import eu.etaxonomy.cdm.model.name.INonViralName;
40
import eu.etaxonomy.cdm.model.name.IZoologicalName;
41
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
42
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
43
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
44
import eu.etaxonomy.cdm.model.name.Rank;
45
import eu.etaxonomy.cdm.model.name.TaxonName;
46
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
47
import eu.etaxonomy.cdm.model.reference.IArticle;
48
import eu.etaxonomy.cdm.model.reference.IBook;
49
import eu.etaxonomy.cdm.model.reference.IBookSection;
50
import eu.etaxonomy.cdm.model.reference.IJournal;
51
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
52
import eu.etaxonomy.cdm.model.reference.IVolumeReference;
53
import eu.etaxonomy.cdm.model.reference.Reference;
54
import eu.etaxonomy.cdm.model.reference.ReferenceType;
55
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
56
import eu.etaxonomy.cdm.test.TermTestBase;
57

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

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

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

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

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

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

    
90
    private NonViralNameParserImpl parser ;
91
    private NomenclaturalCode botanicCode;
92

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

    
99
/*************** TEST *********************************************/
100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
221
        INonViralName nameBasionymAuthor = parser.parseFullName(strNameAbiesBasionymAuthor1Unicode, null, Rank.SPECIES());
222
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
223
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
224
        assertEquals("D'M\u00FCller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitle());
225
        INomenclaturalAuthor basionymTeam = nameBasionymAuthor.getBasionymAuthorship();
226
        assertEquals("Ciardelli", basionymTeam.getNomenclaturalTitle());
227

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
341
    }
342

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

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

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

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

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

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

    
422

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

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

    
449
    }
450

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
766

    
767
    @Test
768
    public final void testUninomials() {
769
        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
770
        INonViralName name = parser.parseFullName(uninomial, botanicCode, null);
771
        assertEquals(Rank.SUBORDER(), name.getRank());
772
    }
773

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

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

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

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

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

    
816
    }
817

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

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

    
836
        //sublusus
837
        infraspecificUnranked = "Genus species sublusus infraspecific";
838
        name = parser.parseFullName(infraspecificUnranked);
839
        assertEquals( "Genus", name.getGenusOrUninomial());
840
        assertEquals( "species", name.getSpecificEpithet());
841
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
842
        assertEquals( "Sublusus should be parsed", Rank.SUBLUSUS(), name.getRank());
843

    
844
        //race
845
        infraspecificUnranked = "Genus species race infraspecific";
846
        name = parser.parseFullName(infraspecificUnranked);
847
        assertEquals( "Genus", name.getGenusOrUninomial());
848
        assertEquals( "species", name.getSpecificEpithet());
849
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
850
        assertEquals( "Race should be parsed", Rank.RACE(), name.getRank());
851
    }
852

    
853
    @Test
854
    public final void testTemp(){
855

    
856
//        String nameStr = "Mentha aquatica L. x Mentha spicata L.";
857
//        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
858
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
859
//        assertFalse( name.getHybridChildRelations().isEmpty());
860
//        for (HybridRelationship rel : name.getHybridChildRelations()){
861
//            TaxonName parent = rel.getParentName();
862
//            System.out.println(parent.getTitleCache());
863
//        }
864
    }
865

    
866
    @Test
867
    public final void testHybridsRemoval(){
868
        //if the parser input already has hybridrelationships they need to be removed
869
        //Create input
870
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
871
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
872
        assertFalse("Name must not have parsing problems", name1.hasProblem());
873
        assertTrue("", name1.getHybridChildRelations().size() == 2);
874

    
875
        hybridCache = "Abieta albana "+UTF8.HYBRID+" Pinuta custa";
876
        boolean makeEmpty = true;
877
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
878
        assertEquals("After parsing another string there should still be 2 parents, but different ones", 2, name1.getHybridChildRelations().size());
879
        assertFalse("Name must not have parsing problems", name1.hasProblem());
880

    
881

    
882
        hybridCache = "Calendula arvensis Mill.";
883
        makeEmpty = true;
884
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
885
        assertTrue("", name1.getHybridChildRelations().isEmpty());
886
        assertFalse("Name must not have parsing problems", name1.hasProblem());
887

    
888

    
889
        //AND the same for reference parsing
890
        hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
891
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
892
        assertFalse("Name must not have parsing problems", name1.hasProblem());
893
        assertTrue("", name1.getHybridChildRelations().size() == 2);
894

    
895
        hybridCache = "Abieta albana "+UTF8.HYBRID+" Pinuta custa";
896
        makeEmpty = true;
897
        parser.parseReferencedName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
898
        assertEquals("After parsing another string there should still be 2 parents, but different ones", 2, name1.getHybridChildRelations().size());
899
        assertFalse("Name must not have parsing problems", name1.hasProblem());
900

    
901
        hybridCache = "Calendula arvensis Mill.";
902
        makeEmpty = true;
903
        parser.parseReferencedName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
904
        assertTrue("", name1.getHybridChildRelations().isEmpty());
905
        assertFalse("Name must not have parsing problems", name1.hasProblem());
906
    }
907

    
908
    private void testName_StringNomcodeRank(Method parseMethod)
909
            throws InvocationTargetException, IllegalAccessException  {
910
        INonViralName name1 = (INonViralName)parseMethod.invoke(parser, strNameAbies1, null, Rank.SPECIES());
911
        //parser.parseFullName(strNameAbies1, null, Rank.SPECIES());
912
        assertEquals("Abies", name1.getGenusOrUninomial());
913
        assertEquals("alba", name1.getSpecificEpithet());
914

    
915
        INonViralName nameAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesAuthor1, null, Rank.SPECIES());
916
        assertEquals("Abies", nameAuthor.getGenusOrUninomial());
917
        assertEquals("alba", nameAuthor.getSpecificEpithet());
918
        assertEquals("Mueller", nameAuthor.getCombinationAuthorship().getNomenclaturalTitle());
919

    
920
        INonViralName nameBasionymAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymAuthor1, null, Rank.SPECIES());
921
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
922
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
923
        assertEquals("D'Mueller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitle());
924
        assertEquals("Ciardelli", nameBasionymAuthor.getBasionymAuthorship().getNomenclaturalTitle());
925

    
926
        INonViralName nameBasionymExAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymExAuthor1, null, Rank.SPECIES());
927
        assertEquals("Abies", nameBasionymExAuthor.getGenusOrUninomial());
928
        assertEquals("alba", nameBasionymExAuthor.getSpecificEpithet());
929
        assertEquals("D'Mueller", nameBasionymExAuthor.getExCombinationAuthorship().getNomenclaturalTitle());
930
        assertEquals("de Greuther", nameBasionymExAuthor.getCombinationAuthorship().getNomenclaturalTitle());
931
        assertEquals("Ciardelli", nameBasionymExAuthor.getExBasionymAuthorship().getNomenclaturalTitle());
932
        assertEquals("Doering", nameBasionymExAuthor.getBasionymAuthorship().getNomenclaturalTitle());
933

    
934
        INonViralName name2 = (INonViralName)parseMethod.invoke(parser, strNameAbiesSub1, null, Rank.SPECIES());
935
        assertEquals("Abies", name2.getGenusOrUninomial());
936
        assertEquals("alba", name2.getSpecificEpithet());
937
        assertEquals("beta", name2.getInfraSpecificEpithet());
938
        assertEquals(Rank.SUBSPECIES(), name2.getRank());
939

    
940

    
941
        // unparseable *********
942
        String problemString = "sdfjlös wer eer wer";
943
        INonViralName nameProblem = (INonViralName)parseMethod.invoke(parser, problemString, null, Rank.SPECIES());
944
        List<ParserProblem> list = nameProblem.getParsingProblems();
945
        assertTrue(nameProblem.getParsingProblem()!=0);
946
        assertEquals(problemString, nameProblem.getTitleCache());
947
    }
948

    
949

    
950
    /**
951
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
952
     */
953
    @Test
954
    public final void testParseNomStatus() {
955
        //nom. ambig.
956
        String strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. ambig.";
957
        INonViralName nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
958
        assertFullRefStandard(nameTestStatus);
959
        assertTrue(nameTestStatus.getStatus().size()== 1);
960
        assertEquals( NomenclaturalStatusType.AMBIGUOUS(), nameTestStatus.getStatus().iterator().next().getType());
961

    
962
        //nom. inval.
963
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. inval.";
964
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
965
        assertFullRefStandard(nameTestStatus);
966
        assertTrue(nameTestStatus.getStatus().size()== 1);
967
        assertEquals( NomenclaturalStatusType.INVALID(), nameTestStatus.getStatus().iterator().next().getType());
968

    
969
        //nom. dub.
970
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. dub.";
971
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
972
        assertFullRefStandard(nameTestStatus);
973
        assertTrue(nameTestStatus.getStatus().size()== 1);
974
        assertEquals( NomenclaturalStatusType.DOUBTFUL(), nameTestStatus.getStatus().iterator().next().getType());
975

    
976
        //nom. confus.
977
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. confus.";
978
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
979
        assertFullRefStandard(nameTestStatus);
980
        assertTrue(nameTestStatus.getStatus().size()== 1);
981
        assertEquals( NomenclaturalStatusType.CONFUSUM(), nameTestStatus.getStatus().iterator().next().getType());
982

    
983
        //nom. illeg.
984
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. illeg.";
985
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
986
        assertFullRefStandard(nameTestStatus);
987
        assertTrue(nameTestStatus.getStatus().size()== 1);
988
        assertEquals( NomenclaturalStatusType.ILLEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
989

    
990
        //nom. superfl.
991
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. superfl.";
992
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
993
        assertFullRefStandard(nameTestStatus);
994
        assertTrue(nameTestStatus.getStatus().size()== 1);
995
        assertEquals( NomenclaturalStatusType.SUPERFLUOUS(), nameTestStatus.getStatus().iterator().next().getType());
996

    
997
        //nom. rej.
998
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. rej.";
999
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1000
        assertFullRefStandard(nameTestStatus);
1001
        assertTrue(nameTestStatus.getStatus().size()== 1);
1002
        assertEquals( NomenclaturalStatusType.REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1003

    
1004
        //nom. utique rej.
1005
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. utique rej.";
1006
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1007
        assertFullRefStandard(nameTestStatus);
1008
        assertTrue(nameTestStatus.getStatus().size()== 1);
1009
        assertEquals( NomenclaturalStatusType.UTIQUE_REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1010

    
1011
        //nom. cons. prop.
1012
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons. prop.";
1013
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1014
        assertFullRefStandard(nameTestStatus);
1015
        assertTrue(nameTestStatus.getStatus().size()== 1);
1016
        assertEquals( NomenclaturalStatusType.CONSERVED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1017

    
1018
        //nom. orth. cons. prop.
1019
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, orth. cons. prop.";
1020
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1021
        assertFullRefStandard(nameTestStatus);
1022
        assertTrue(nameTestStatus.getStatus().size()== 1);
1023
        assertEquals( NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1024

    
1025
        //nom. cons. prop.
1026
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons. des.";
1027
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1028
        assertFullRefStandard(nameTestStatus);
1029
        assertTrue(nameTestStatus.getStatus().size()== 1);
1030
        assertEquals( NomenclaturalStatusType.CONSERVED_DESIG(), nameTestStatus.getStatus().iterator().next().getType());
1031

    
1032
        //nom. legit.
1033
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. legit.";
1034
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1035
        assertFullRefStandard(nameTestStatus);
1036
        assertTrue(nameTestStatus.getStatus().size()== 1);
1037
        assertEquals( NomenclaturalStatusType.LEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
1038

    
1039
        //nom. altern.
1040
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. altern.";
1041
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1042
        assertFullRefStandard(nameTestStatus);
1043
        assertTrue(nameTestStatus.getStatus().size()== 1);
1044
        assertEquals( NomenclaturalStatusType.ALTERNATIVE(), nameTestStatus.getStatus().iterator().next().getType());
1045

    
1046
        //nom. alternativ.
1047
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. alternativ.";
1048
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1049
        assertFullRefStandard(nameTestStatus);
1050
        assertTrue(nameTestStatus.getStatus().size()== 1);
1051
        assertEquals( NomenclaturalStatusType.ALTERNATIVE(), nameTestStatus.getStatus().iterator().next().getType());
1052

    
1053
        //nom. nov.
1054
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. nov.";
1055
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1056
        assertFullRefStandard(nameTestStatus);
1057
        assertTrue(nameTestStatus.getStatus().size()== 1);
1058
        assertEquals( NomenclaturalStatusType.NOVUM(), nameTestStatus.getStatus().iterator().next().getType());
1059

    
1060
        //nom. utique rej. prop.
1061
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. utique rej. prop.";
1062
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1063
        assertFullRefStandard(nameTestStatus);
1064
        assertTrue(nameTestStatus.getStatus().size()== 1);
1065
        assertEquals( NomenclaturalStatusType.UTIQUE_REJECTED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1066

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

    
1074
        //nom. rej. prop.
1075
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. rej. prop.";
1076
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1077
        assertFullRefStandard(nameTestStatus);
1078
        assertTrue(nameTestStatus.getStatus().size()== 1);
1079
        assertEquals( NomenclaturalStatusType.REJECTED_PROP(), nameTestStatus.getStatus().iterator().next().getType());
1080

    
1081
        //nom. cons.
1082
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. cons.";
1083
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1084
        assertFullRefStandard(nameTestStatus);
1085
        assertTrue(nameTestStatus.getStatus().size()== 1);
1086
        assertEquals( NomenclaturalStatusType.CONSERVED(), nameTestStatus.getStatus().iterator().next().getType());
1087

    
1088
        //nom. sanct.
1089
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. sanct.";
1090
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1091
        assertFullRefStandard(nameTestStatus);
1092
        assertTrue(nameTestStatus.getStatus().size()== 1);
1093
        assertEquals( NomenclaturalStatusType.SANCTIONED(), nameTestStatus.getStatus().iterator().next().getType());
1094

    
1095
        //nom. nud.
1096
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. nud.";
1097
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1098
        assertFullRefStandard(nameTestStatus);
1099
        assertTrue(nameTestStatus.getStatus().size()== 1);
1100
        assertEquals( NomenclaturalStatusType.NUDUM(), nameTestStatus.getStatus().iterator().next().getType());
1101

    
1102
        //comb. inval.
1103
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. inval.";
1104
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1105
        assertFullRefStandard(nameTestStatus);
1106
        assertTrue(nameTestStatus.getStatus().size()== 1);
1107
        assertEquals( NomenclaturalStatusType.COMBINATION_INVALID(), nameTestStatus.getStatus().iterator().next().getType());
1108

    
1109
        //comb. illeg.
1110
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. illeg.";
1111
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1112
        assertFullRefStandard(nameTestStatus);
1113
        assertTrue(nameTestStatus.getStatus().size()== 1);
1114
        assertEquals( NomenclaturalStatusType.COMBINATION_ILLEGITIMATE(), nameTestStatus.getStatus().iterator().next().getType());
1115

    
1116
        //nom. provis.
1117
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. provis.";
1118
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1119
        assertFullRefStandard(nameTestStatus);
1120
        assertTrue(nameTestStatus.getStatus().size()== 1);
1121
        assertEquals( NomenclaturalStatusType.PROVISIONAL(), nameTestStatus.getStatus().iterator().next().getType());
1122

    
1123
        //nom. val.
1124
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. val.";
1125
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1126
        assertFullRefStandard(nameTestStatus);
1127
        assertTrue(nameTestStatus.getStatus().size()== 1);
1128
        assertEquals( NomenclaturalStatusType.VALID(), nameTestStatus.getStatus().iterator().next().getType());
1129

    
1130
        //nom. subnud.
1131
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. subnud.";
1132
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1133
        assertFullRefStandard(nameTestStatus);
1134
        assertTrue(nameTestStatus.getStatus().size()== 1);
1135
        assertEquals( NomenclaturalStatusType.SUBNUDUM(), nameTestStatus.getStatus().iterator().next().getType());
1136

    
1137
        //opus. utique oppr.
1138
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, op. utique oppr.";
1139
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1140
        assertFullRefStandard(nameTestStatus);
1141
        assertTrue(nameTestStatus.getStatus().size()== 1);
1142
        assertEquals( NomenclaturalStatusType.OPUS_UTIQUE_OPPR(), nameTestStatus.getStatus().iterator().next().getType());
1143

    
1144
        //comb. nov.
1145
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, comb. nov.";
1146
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1147
        assertFullRefStandard(nameTestStatus);
1148
        assertTrue(nameTestStatus.getStatus().size()== 1);
1149
        assertEquals( NomenclaturalStatusType.COMB_NOV(), nameTestStatus.getStatus().iterator().next().getType());
1150

    
1151
        //orth. rej.
1152
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, orth. rej.";
1153
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1154
        assertFullRefStandard(nameTestStatus);
1155
        assertTrue(nameTestStatus.getStatus().size()== 1);
1156
        assertEquals( NomenclaturalStatusType.ORTHOGRAPHY_REJECTED(), nameTestStatus.getStatus().iterator().next().getType());
1157

    
1158
        //ined.
1159
        strTestStatus = "Houstonia macvaughii (Terrell), ined.";
1160
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1161
        assertEquals("Houstonia", nameTestStatus.getGenusOrUninomial());
1162
        assertEquals("macvaughii", nameTestStatus.getSpecificEpithet());
1163
        assertEquals("(Terrell)", nameTestStatus.getAuthorshipCache());
1164
        assertEquals(1, nameTestStatus.getStatus().size());
1165
        assertEquals( NomenclaturalStatusType.INED(), nameTestStatus.getStatus().iterator().next().getType());
1166

    
1167
        //not yet parsed "not avail."
1168
    }
1169

    
1170
    /**
1171
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
1172
     */
1173
    @Test
1174
    public final void testParseReferencedName() {
1175
        try {
1176
            Method parseMethod = parser.getClass().getDeclaredMethod("parseReferencedName", String.class, NomenclaturalCode.class, Rank.class);
1177
            testName_StringNomcodeRank(parseMethod);
1178
        } catch (Exception e) {
1179
            e.printStackTrace();
1180
            assertTrue(false);
1181
        }
1182

    
1183
        //null
1184
        String strNull = null;
1185
        Rank rankSpecies = Rank.SPECIES();
1186
        INonViralName nameNull = parser.parseReferencedName(strNull, null, rankSpecies);
1187
        assertNull(nameNull);
1188

    
1189
        //Empty
1190
        String strEmpty = "";
1191
        INonViralName nameEmpty = parser.parseReferencedName(strEmpty, null, rankSpecies);
1192
        assertFalse(nameEmpty.hasProblem());
1193
        assertEquals(strEmpty, nameEmpty.getFullTitleCache());
1194
        assertNull(nameEmpty.getNomenclaturalMicroReference());
1195

    
1196

    
1197
        //Whitespaces
1198
        String strFullWhiteSpcaceAndDot = "Abies alba Mill.,  Sp.   Pl.  4:  455 .  1987 .";
1199
        INonViralName namefullWhiteSpcaceAndDot = parser.parseReferencedName(strFullWhiteSpcaceAndDot, null, rankSpecies);
1200
        assertFullRefStandard(namefullWhiteSpcaceAndDot);
1201
        assertTrue(namefullWhiteSpcaceAndDot.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1202
        assertEquals( "Abies alba Mill., Sp. Pl. 4: 455. 1987", namefullWhiteSpcaceAndDot.getFullTitleCache());
1203

    
1204
        //Book
1205
        String fullReference = "Abies alba Mill., Sp. Pl. 4: 455. 1987";
1206
        INonViralName name1 = parser.parseReferencedName(fullReference, null, rankSpecies);
1207
        assertFullRefStandard(name1);
1208
        assertTrue(name1.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1209
        assertEquals(fullReference, name1.getFullTitleCache());
1210
        assertTrue("Name author and reference author should be the same", name1.getCombinationAuthorship() == name1.getNomenclaturalReference().getAuthorship());
1211

    
1212
        //Book Section
1213
        fullReference = "Abies alba Mill. in Otto, Sp. Pl. 4(6): 455. 1987";
1214
        INonViralName name2 = parser.parseReferencedName(fullReference + ".", null, rankSpecies);
1215
        assertFullRefNameStandard(name2);
1216
        assertEquals(fullReference, name2.getFullTitleCache());
1217
        assertFalse(name2.hasProblem());
1218
        INomenclaturalReference ref = name2.getNomenclaturalReference();
1219
        assertEquals(ReferenceType.BookSection, ((Reference)ref).getType());
1220
        IBookSection bookSection = (IBookSection) ref;
1221
        IBook inBook = bookSection.getInBook();
1222
        assertNotNull(inBook);
1223
        assertNotNull(inBook.getAuthorship());
1224
        assertEquals("Otto", inBook.getAuthorship().getTitleCache());
1225
        assertEquals("Otto: Sp. Pl. 4(6).", inBook.getTitleCache());
1226
        assertEquals("Sp. Pl.", inBook.getAbbrevTitle());
1227
        assertEquals("4(6)", inBook.getVolume());
1228
        assertTrue("Name author and reference author should be the same", name2.getCombinationAuthorship() == name2.getNomenclaturalReference().getAuthorship());
1229

    
1230
        //Article
1231
        fullReference = "Abies alba Mill. in Sp. Pl. 4(6): 455. 1987";
1232
        INonViralName name3 = parser.parseReferencedName(fullReference, null, rankSpecies);
1233
        assertFullRefNameStandard(name3);
1234
        name3.setTitleCache(null);
1235
        assertEquals(fullReference, name3.getFullTitleCache());
1236
        assertFalse(name3.hasProblem());
1237
        ref = name3.getNomenclaturalReference();
1238
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1239
        //Article article = (Article)ref;
1240
        IJournal journal = ((IArticle)ref).getInJournal();
1241
        assertNotNull(journal);
1242
        //assertEquals("Sp. Pl. 4(6)", inBook.getTitleCache());
1243
        assertEquals("Sp. Pl.",((Reference) journal).getTitleCache());
1244
        assertEquals("Sp. Pl.", journal.getAbbrevTitle());
1245
        assertEquals("4(6)",((IArticle)ref).getVolume());
1246
        assertTrue("Name author and reference author should be the same", name3.getCombinationAuthorship() == name3.getNomenclaturalReference().getAuthorship());
1247

    
1248
        //Article with volume range
1249
        fullReference = "Abies alba Mill. in Sp. Pl. 4(1-2): 455. 1987";
1250
        INonViralName name3a = parser.parseReferencedName(fullReference, null, rankSpecies);
1251
        name3a.setTitleCache(null);
1252
        assertEquals(fullReference, name3a.getFullTitleCache());
1253
        assertFalse(name3a.hasProblem());
1254
        ref = name3a.getNomenclaturalReference();
1255
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1256
        assertEquals("4(1-2)",((IArticle)ref).getVolume());
1257

    
1258
        //SoftArticle - having "," on position > 4
1259
        String journalTitle = "Bull. Soc. Bot.France. Louis., Roi";
1260
        String yearPart = " 1987 - 1989";
1261
        String parsedYear = "1987-1989";
1262
        String parsedYearFormatted = "1987"+SEP+"1989";
1263
        String fullReferenceWithoutYear = "Abies alba Mill. in " + journalTitle + " 4(6): 455.";
1264
        fullReference = fullReferenceWithoutYear + yearPart;
1265
        String fullReferenceWithEnd = fullReference + ".";
1266
        INonViralName name4 = parser.parseReferencedName(fullReferenceWithEnd, null, rankSpecies);
1267
        assertFalse(name4.hasProblem());
1268
        assertFullRefNameStandard(name4);
1269
        assertEquals(fullReferenceWithoutYear + " " + parsedYearFormatted, name4.getFullTitleCache());
1270
        ref = name4.getNomenclaturalReference();
1271
        assertEquals(ReferenceType.Article, ref.getType());
1272
        //article = (Article)ref;
1273
        assertEquals(parsedYearFormatted, ref.getYear());
1274
        journal = ((IArticle)ref).getInJournal();
1275
        assertNotNull(journal);
1276
        assertEquals(journalTitle, ((Reference) journal).getTitleCache());
1277
        assertEquals(journalTitle, journal.getAbbrevTitle());
1278
        assertEquals("4(6)", ((IArticle)ref).getVolume());
1279

    
1280
        //Zoo name
1281
        String strNotParsableZoo = "Abies alba M., 1923, Sp. P. xxwer4352, nom. inval.";
1282
        IZoologicalName nameZooRefNotParsabel = parser.parseReferencedName(strNotParsableZoo, null, null);
1283
        assertTrue(nameZooRefNotParsabel.hasProblem());
1284
        List<ParserProblem> list = nameZooRefNotParsabel.getParsingProblems();
1285
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1286
        assertEquals(21, nameZooRefNotParsabel.getProblemStarts());
1287
        assertEquals(37, nameZooRefNotParsabel.getProblemEnds());
1288
        assertTrue(nameZooRefNotParsabel.getNomenclaturalReference().hasProblem());
1289
        list = nameZooRefNotParsabel.getNomenclaturalReference().getParsingProblems();
1290
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1291

    
1292
        assertEquals(NomenclaturalCode.ICZN, nameZooRefNotParsabel.getNameType());
1293
        assertEquals(Integer.valueOf(1923), nameZooRefNotParsabel.getPublicationYear());
1294
        assertEquals(1, nameZooRefNotParsabel.getStatus().size());
1295

    
1296
        String strZooNameSineYear = "Homo sapiens L., 1758, Sp. An. 3: 345";
1297
        IZoologicalName nameZooNameSineYear = parser.parseReferencedName(strZooNameSineYear);
1298
        assertFalse(nameZooNameSineYear.hasProblem());
1299
        assertEquals("Name without reference year must have year", (Integer)1758, nameZooNameSineYear.getPublicationYear());
1300
        assertEquals("Name without reference year must have year", "1758", nameZooNameSineYear.getNomenclaturalReference().getYear());
1301

    
1302
        String strZooNameNewCombination = "Homo sapiens (L., 1758) Mill., 1830, Sp. An. 3: 345";
1303
        IZoologicalName nameZooNameNewCombination = parser.parseReferencedName(strZooNameNewCombination);
1304
        assertTrue(nameZooNameNewCombination.hasProblem());
1305
        list = nameZooNameNewCombination.getParsingProblems();
1306
        assertTrue("List must contain new combination has publication warning ", list.contains(ParserProblem.NewCombinationHasPublication));
1307
        assertEquals(35, nameZooNameNewCombination.getProblemStarts());
1308
        assertEquals(51, nameZooNameNewCombination.getProblemEnds());
1309

    
1310
        //Special MicroRefs
1311
        String strSpecDetail1 = "Abies alba Mill. in Sp. Pl. 4(6): [455]. 1987";
1312
        INonViralName nameSpecDet1 = parser.parseReferencedName(strSpecDetail1 + ".", null, rankSpecies);
1313
        assertFalse(nameSpecDet1.hasProblem());
1314
        assertEquals(strSpecDetail1, nameSpecDet1.getFullTitleCache());
1315
        assertEquals("[455]", nameSpecDet1.getNomenclaturalMicroReference());
1316

    
1317
        //Special MicroRefs
1318
        String strSpecDetail2 = "Abies alba Mill. in Sp. Pl. 4(6): couv. 2. 1987";
1319
        INonViralName nameSpecDet2 = parser.parseReferencedName(strSpecDetail2 + ".", null, rankSpecies);
1320
        assertFalse(nameSpecDet2.hasProblem());
1321
        assertEquals(strSpecDetail2, nameSpecDet2.getFullTitleCache());
1322
        assertEquals("couv. 2", nameSpecDet2.getNomenclaturalMicroReference());
1323

    
1324
        //Special MicroRefs
1325
        String strSpecDetail3 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455. 1987";
1326
        INonViralName nameSpecDet3 = parser.parseReferencedName(strSpecDetail3 + ".", null, rankSpecies);
1327
        assertFalse(nameSpecDet3.hasProblem());
1328
        assertEquals(strSpecDetail3, nameSpecDet3.getFullTitleCache());
1329
        assertEquals("fig. 455", nameSpecDet3.getNomenclaturalMicroReference());
1330

    
1331
        //Special MicroRefs
1332
        String strSpecDetail4 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455-567. 1987";
1333
        fullReference = strSpecDetail4 + ".";
1334
        INonViralName nameSpecDet4 = parser.parseReferencedName(fullReference, null, rankSpecies);
1335
        assertFalse(nameSpecDet4.hasProblem());
1336
        assertEquals(strSpecDetail4, nameSpecDet4.getFullTitleCache());
1337
        assertEquals("fig. 455-567", nameSpecDet4.getNomenclaturalMicroReference());
1338

    
1339
        //Special MicroRefs
1340
        String strSpecDetail5 = "Abies alba Mill. in Sp. Pl. 4(6): Gard n\u00B0 4. 1987";
1341
        fullReference = strSpecDetail5 + ".";
1342
        INonViralName nameSpecDet5 = parser.parseReferencedName(fullReference, null, rankSpecies);
1343
        assertFalse(nameSpecDet5.hasProblem());
1344
        assertEquals(strSpecDetail5, nameSpecDet5.getFullTitleCache());
1345
        assertEquals("Gard n\u00B0 4", nameSpecDet5.getNomenclaturalMicroReference());
1346

    
1347
        //Special MicroRefs
1348
        String strSpecDetail6 = "Abies alba Mill. in Sp. Pl. 4(6): 455a. 1987";
1349
        fullReference = strSpecDetail6 + ".";
1350
        INonViralName nameSpecDet6 = parser.parseReferencedName(fullReference, null, rankSpecies);
1351
        assertFalse(nameSpecDet6.hasProblem());
1352
        assertEquals(strSpecDetail6, nameSpecDet6.getFullTitleCache());
1353
        assertEquals("455a", nameSpecDet6.getNomenclaturalMicroReference());
1354

    
1355
        //Special MicroRefs
1356
        String strSpecDetail7 = "Abies alba Mill. in Sp. Pl. 4(6): pp.455-457. 1987";
1357
        fullReference = strSpecDetail7 + ".";
1358
        INonViralName nameSpecDet7 = parser.parseReferencedName(fullReference, null, rankSpecies);
1359
        assertFalse(nameSpecDet7.hasProblem());
1360
        assertEquals(strSpecDetail7, nameSpecDet7.getFullTitleCache());
1361
        assertEquals("pp.455-457", nameSpecDet7.getNomenclaturalMicroReference());
1362

    
1363
        //Special MicroRefs
1364
        String strSpecDetail8 = "Abies alba Mill. in Sp. Pl. 4(6): ppp.455-457. 1987";
1365
        INonViralName nameSpecDet8 = parser.parseReferencedName(strSpecDetail8, null, rankSpecies);
1366
        assertTrue(nameSpecDet8.hasProblem());
1367
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1368
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after -457
1369

    
1370

    
1371
        //Special MicroRefs
1372
        String strSpecDetail9 = "Abies alba Mill. in Sp. Pl. 4(6): pp. 455 - 457. 1987";
1373
        INonViralName nameSpecDet9 = parser.parseReferencedName(strSpecDetail9, null, rankSpecies);
1374
        assertFalse(nameSpecDet9.hasProblem());
1375
        assertEquals(strSpecDetail9, nameSpecDet9.getFullTitleCache());
1376
        assertEquals("pp. 455 - 457", nameSpecDet9.getNomenclaturalMicroReference());
1377

    
1378
        //Special MicroRefs
1379
        String strSpecDetail10 = "Abies alba Mill. in Sp. Pl. 4(6): p 455. 1987";
1380
        INonViralName nameSpecDet10 = parser.parseReferencedName(strSpecDetail10, null, rankSpecies);
1381
        assertFalse(nameSpecDet10.hasProblem());
1382
        assertEquals(strSpecDetail10, nameSpecDet10.getFullTitleCache());
1383
        assertEquals("p 455", nameSpecDet10.getNomenclaturalMicroReference());
1384

    
1385
        //Special MicroRefs
1386
        String strSpecDetail11 = "Abies alba Mill. in Sp. Pl. 4(6): p. 455 - 457. 1987";
1387
        INonViralName nameSpecDet11 = parser.parseReferencedName(strSpecDetail11, null, rankSpecies);
1388
        assertTrue(nameSpecDet11.hasProblem());
1389
        list = nameSpecDet11.getParsingProblems();
1390
        assertTrue("Problem is Detail. Must be pp.", list.contains(ParserProblem.CheckDetailOrYear));
1391
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1392
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after - 457
1393

    
1394

    
1395
        //no volume, no edition
1396
        String strNoVolume = "Abies alba Mill., Sp. Pl.: 455. 1987";
1397
        INonViralName nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1398
        assertFalse(nameNoVolume.hasProblem());
1399
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1400
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1401
        assertEquals(null, ((IBook)nameNoVolume.getNomenclaturalReference()).getEdition());
1402

    
1403
        //volume, no edition
1404
        strNoVolume = "Abies alba Mill., Sp. Pl. 2: 455. 1987";
1405
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1406
        assertFalse(nameNoVolume.hasProblem());
1407
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1408
        assertEquals("2", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1409
        assertEquals(null, ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1410

    
1411
        //no volume, edition
1412
        strNoVolume = "Abies alba Mill., Sp. Pl., ed. 3: 455. 1987";
1413
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1414
        assertFalse(nameNoVolume.hasProblem());
1415
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1416
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1417
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1418

    
1419
        //volume, edition
1420
        strNoVolume = "Abies alba Mill., Sp. Pl. ed. 3, 4(5): 455. 1987";
1421
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1422
        assertFalse(nameNoVolume.hasProblem());
1423
        assertEquals(strNoVolume.replace(" ed.", ", ed."), nameNoVolume.getFullTitleCache());
1424
        assertEquals("4(5)", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1425
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1426

    
1427
        String strUnparsableInRef = "Abies alba Mill. in -er46: 455. 1987";
1428
        INonViralName nameUnparsableInRef = parser.parseReferencedName(strUnparsableInRef, null, rankSpecies);
1429
        assertTrue(nameUnparsableInRef.hasProblem());
1430
        list = nameUnparsableInRef.getParsingProblems();
1431
        assertTrue("Unparsable title", list.contains(ParserProblem.UnparsableReferenceTitle));
1432
        assertEquals(strUnparsableInRef, nameUnparsableInRef.getFullTitleCache());
1433
        assertEquals(20, nameUnparsableInRef.getProblemStarts());
1434
        assertEquals(25, nameUnparsableInRef.getProblemEnds());
1435

    
1436

    
1437
        //volume, edition
1438
        String strNoSeparator = "Abies alba Mill. Sp. Pl. ed. 3, 4(5): 455. 1987";
1439
        INonViralName nameNoSeparator = parser.parseReferencedName(strNoSeparator, ICNAFP, rankSpecies);
1440
        assertTrue(nameNoSeparator.hasProblem());
1441
        list = nameNoSeparator.getParsingProblems();
1442
        assertTrue("Problem is missing name-reference separator", list.contains(ParserProblem.NameReferenceSeparation));
1443
        assertEquals(strNoSeparator, nameNoSeparator.getFullTitleCache());
1444
        assertEquals(10, nameNoSeparator.getProblemStarts()); //TODO better start behind Mill. (?)
1445
        assertEquals(47, nameNoSeparator.getProblemEnds());   //TODO better stop before :
1446

    
1447
        String strUnparsableInRef2 = "Hieracium pepsicum L., My Bookkkk 1. 1903";
1448
        INonViralName nameUnparsableInRef2 = parser.parseReferencedName(strUnparsableInRef2, null, rankSpecies);
1449
        assertTrue(nameUnparsableInRef2.hasProblem());
1450
        list = nameUnparsableInRef2.getParsingProblems();
1451
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1452
        assertEquals(strUnparsableInRef2, nameUnparsableInRef2.getFullTitleCache());
1453
        assertEquals(23, nameUnparsableInRef2.getProblemStarts());
1454
        assertEquals(41, nameUnparsableInRef2.getProblemEnds());
1455

    
1456

    
1457
        String strUnparsableInRef3 = "Hieracium pespcim N., My Bookkkk 1. 1902";
1458
        INonViralName nameUnparsableInRef3 = parser.parseReferencedName(strUnparsableInRef3, null, null);
1459
        assertTrue(nameUnparsableInRef3.hasProblem());
1460
        list = nameUnparsableInRef3.getParsingProblems();
1461
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1462
        assertEquals(strUnparsableInRef3, nameUnparsableInRef3.getFullTitleCache());
1463
        assertEquals(22, nameUnparsableInRef3.getProblemStarts());
1464
        assertEquals(40, nameUnparsableInRef3.getProblemEnds());
1465

    
1466
        String strUnparsableInRef4 = "Hieracium pepsicum (Hsllreterto) L., My Bookkkk 1. 1903";
1467
        INonViralName nameUnparsableInRef4 = parser.parseReferencedName(strUnparsableInRef4, null, null);
1468
        assertTrue(nameUnparsableInRef4.hasProblem());
1469
        list = nameUnparsableInRef4.getParsingProblems();
1470
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1471
        assertEquals(strUnparsableInRef4, nameUnparsableInRef4.getFullTitleCache());
1472
        assertEquals(37, nameUnparsableInRef4.getProblemStarts());
1473
        assertEquals(55, nameUnparsableInRef4.getProblemEnds());
1474

    
1475
        String strSameName = "Hieracium pepcum (Hsllreterto) L., My Bokkk 1. 1903";
1476
        INonViralName nameSameName = nameUnparsableInRef4;
1477
        parser.parseReferencedName(nameSameName, strSameName, null, true);
1478
        assertTrue(nameSameName.hasProblem());
1479
        list = nameSameName.getParsingProblems();
1480
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1481
        assertEquals(strSameName, nameSameName.getFullTitleCache());
1482
        assertEquals(35, nameSameName.getProblemStarts());
1483
        assertEquals(51, nameSameName.getProblemEnds());
1484

    
1485
        String strGenusUnparse = "Hieracium L., jlklk";
1486
        INonViralName nameGenusUnparse =
1487
            parser.parseReferencedName(strGenusUnparse, null, null);
1488
        assertTrue(nameGenusUnparse.hasProblem());
1489
        list = nameGenusUnparse.getParsingProblems();
1490
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1491
        assertTrue("Problem uninomial", list.contains(ParserProblem.CheckRank));
1492
        assertEquals(strGenusUnparse, nameGenusUnparse.getFullTitleCache());
1493
        assertEquals(0, nameGenusUnparse.getProblemStarts());
1494
        assertEquals(19, nameGenusUnparse.getProblemEnds());
1495

    
1496
        String strGenusUnparse2 = "Hieracium L., Per Luigi: 44. 1987";
1497
        INonViralName nameGenusUnparse2 =
1498
            parser.parseReferencedName(strGenusUnparse2, null, Rank.FAMILY());
1499
        assertFalse(nameGenusUnparse2.hasProblem());
1500
        assertEquals(strGenusUnparse2, nameGenusUnparse2.getFullTitleCache());
1501
        assertEquals(-1, nameGenusUnparse2.getProblemStarts());
1502
        assertEquals(-1, nameGenusUnparse2.getProblemEnds());
1503

    
1504
        String strBookSection2 = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz, ed. 2, 2: 288. 1905-1907";
1505
        String strBookSection2NoComma = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905-1907";
1506
        INonViralName nameBookSection2 =
1507
              parser.parseReferencedName(strBookSection2, null, null);
1508
        assertFalse(nameBookSection2.hasProblem());
1509
        nameBookSection2.setFullTitleCache(null, false);
1510
        assertEquals(strBookSection2NoComma.replace(" ed.", ", ed.").replace("-",SEP), nameBookSection2.getFullTitleCache());
1511
        assertEquals(-1, nameBookSection2.getProblemStarts());
1512
        assertEquals(-1, nameBookSection2.getProblemEnds());
1513
        assertNull((nameBookSection2.getNomenclaturalReference()).getDatePublished().getStart());
1514
        assertEquals("1905"+SEP+"1907", ((IBookSection)nameBookSection2.getNomenclaturalReference()).getInBook().getDatePublished().getYear());
1515

    
1516
        String strBookSection = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905";
1517
        INonViralName nameBookSection =
1518
            parser.parseReferencedName(strBookSection, null, null);
1519
        assertFalse(nameBookSection.hasProblem());
1520
        assertEquals(strBookSection.replace(" ed.", ", ed."), nameBookSection.getFullTitleCache());
1521
        assertEquals(-1, nameBookSection.getProblemStarts());
1522
        assertEquals(-1, nameBookSection.getProblemEnds());
1523
        assertNull(((IBookSection)nameBookSection.getNomenclaturalReference()).getInBook().getDatePublished().getStart());
1524
        assertEquals("1905", ((IBookSection)nameBookSection.getNomenclaturalReference()).getDatePublished().getYear());
1525

    
1526
        String strXXXs = "Abies alba, Soer der 1987";
1527
        INonViralName problemName = parser.parseReferencedName(strXXXs, null, null);
1528
        assertTrue(problemName.hasProblem());
1529
        list = problemName.getParsingProblems();
1530
        assertTrue("Problem must be name-reference separation", list.contains(ParserProblem.NameReferenceSeparation));
1531
        parser.parseReferencedName(problemName, strBookSection, null, true);
1532
        assertFalse(problemName.hasProblem());
1533

    
1534
        problemName = parser.parseFullName(strXXXs, null, null);
1535
        assertTrue(problemName.hasProblem());
1536
        list = problemName.getParsingProblems();
1537
        assertTrue("Name part must be unparsable", list.contains(ParserProblem.UnparsableNamePart));
1538

    
1539

    
1540
        String testParsable = "Pithecellobium macrostachyum Benth.";
1541
        assertTrue(isParsable(testParsable, ICNAFP));
1542

    
1543
        testParsable = "Pithecellobium macrostachyum (Benth.)";
1544
        assertTrue(isParsable(testParsable, ICNAFP));
1545

    
1546
        testParsable = "Pithecellobium macrostachyum (Benth., 1845)";
1547
        assertTrue(isParsable(testParsable, NomenclaturalCode.ICZN));
1548

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

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

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

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

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

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

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

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

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

    
1580
        testParsable = "Hieracium lachenalii, Ill. Fl. (Mitt.) 6: 1285. 1929";
1581
        assertFalse("Author is obligatory if followed by reference", isParsable(testParsable, ICNAFP));
1582
        assertTrue("Problem must be name-reference separation", getProblems(testParsable, ICNAFP).
1583
                contains(ParserProblem.NameReferenceSeparation));
1584

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

    
1590
        testParsable = "Abies alba Mill. var. alba";
1591
        assertTrue("Autonym problem", isParsable(testParsable, ICNAFP));
1592

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

    
1596

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

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

    
1604

    
1605
    }
1606

    
1607

    
1608
    /**
1609
     * Test author with name parts van, von, de, de la, d', da, del.
1610
     * See also https://dev.e-taxonomy.eu/redmine/issues/3373
1611
     */
1612
    @Test
1613
    public final void  testComposedAuthorNames(){
1614

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

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

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

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

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

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

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

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

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

    
1651
    }
1652

    
1653

    
1654

    
1655
    /**
1656
     * @param testParsable
1657
     * @param icbn
1658
     * @return
1659
     */
1660
    private List<ParserProblem> getProblems(String string, NomenclaturalCode code) {
1661
        List<ParserProblem> result = parser.parseReferencedName(string, code, null).getParsingProblems();
1662
        return result;
1663
    }
1664

    
1665
    private boolean isParsable(String string, NomenclaturalCode code){
1666
        INonViralName name = parser.parseReferencedName(string, code, null);
1667
        return ! name.hasProblem();
1668
    }
1669

    
1670
    private void assertFullRefNameStandard(INonViralName name){
1671
        assertEquals("Abies", name.getGenusOrUninomial());
1672
        assertEquals("alba", name.getSpecificEpithet());
1673
        assertEquals("Mill.", name.getAuthorshipCache());
1674
        assertEquals("455", name.getNomenclaturalMicroReference());
1675
        assertNotNull(name.getNomenclaturalReference());
1676
    }
1677

    
1678
    private void assertFullRefStandard(INonViralName name){
1679
        assertEquals("Abies", name.getGenusOrUninomial());
1680
        assertEquals("alba", name.getSpecificEpithet());
1681
        assertEquals("Mill.", name.getAuthorshipCache());
1682
        assertEquals("455", name.getNomenclaturalMicroReference());
1683
        assertNotNull(name.getNomenclaturalReference());
1684
        INomenclaturalReference ref = name.getNomenclaturalReference();
1685
        assertEquals("1987", ref.getYear());
1686
        assertEquals("Sp. Pl.", ref.getAbbrevTitle());
1687
    }
1688

    
1689

    
1690
    @Test
1691
    public void testNeverEndingParsing(){
1692
        //some full titles result in never ending parsing process https://dev.e-taxonomy.eu/redmine/issues/1556
1693

    
1694
        String irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1695
//      irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Uiuis Iuiui Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1696
        INonViralName nvn = this.parser.parseReferencedName(irinaExample, NomenclaturalCode.ICZN, null);
1697
        int parsingProblem = nvn.getParsingProblem();
1698
        Assert.assertEquals("Name should have only rank warning", 1, parsingProblem);
1699
        Assert.assertEquals("Titlecache", "Milichiidae Sharp, 1899", nvn.getTitleCache());
1700
        Assert.assertEquals("If this line reached everything should be ok", "Milichiidae", nvn.getGenusOrUninomial());
1701

    
1702
        String anotherExample = "Scorzonera hispanica var. brevifolia Boiss. & Balansa in Boissier, Diagn. Pl. Orient., ser. 2 6: 119. 1859.";
1703
        nvn = this.parser.parseReferencedName(anotherExample, ICNAFP, null);
1704
        parsingProblem = nvn.getParsingProblem();
1705
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
1706
        Assert.assertEquals("Titlecache", "Scorzonera hispanica var. brevifolia Boiss. & Balansa", nvn.getTitleCache());
1707
        Assert.assertEquals("If this line reached everything should be ok", "Scorzonera", nvn.getGenusOrUninomial());
1708

    
1709
        String unparsable = "Taraxacum nevskii L., Trudy Bot. Inst. Nauk S.S.S.R., Ser. 1, Fl. Sist. Vyssh. Rast. 4: 293. 1937.";
1710
//      String unparsableA = "Taraxacum nevskii L. in Trudy Bot. Inst. Nauk: 293. 1937.";
1711
        nvn = this.parser.parseReferencedName(unparsable, ICNAFP, null);
1712
        Assert.assertEquals("Titlecache", "Taraxacum nevskii L.", nvn.getTitleCache());
1713
        Assert.assertEquals("If this line reached everything should be ok", "Taraxacum", nvn.getGenusOrUninomial());
1714
        parsingProblem = nvn.getParsingProblem();
1715
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1716

    
1717
        String unparsable2 = "Hieracium pxxx Dahlst., Kongl. Svenska Vetensk. Acad. Handl. ser. 2, 26(3): 255. 1894";
1718
//      String unparsable2A = "Hieracium pxxx Dahlst., Kongl Svenska Vetensk Acad Handl, 26: 255. 1894.";
1719
        nvn = this.parser.parseReferencedName(unparsable2, ICNAFP, null);
1720
        Assert.assertEquals("Titlecache", "Hieracium pxxx Dahlst.", nvn.getTitleCache());
1721
        Assert.assertEquals("If this line reached everything should be ok", "Hieracium", nvn.getGenusOrUninomial());
1722
        parsingProblem = nvn.getParsingProblem();
1723
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1724

    
1725

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

    
1731
    }
1732

    
1733

    
1734
    @Test
1735
    public final void testSeries(){
1736
        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea, n.s., 9: 31. 1958";
1737
        INonViralName name = parser.parseReferencedName(parseStr);
1738
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1739
        Reference nomRef = name.getNomenclaturalReference();
1740
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1741

    
1742
        assertEquals(ReferenceType.Article, nomRef.getType());
1743
        assertEquals(name.getNomenclaturalMicroReference(), "31");
1744
        assertEquals("Nova Guinea", nomRef.getInJournal().getAbbrevTitle());
1745
        assertEquals("n.s.", nomRef.getSeriesPart());
1746
    }
1747

    
1748
    @Test
1749
    @Ignore
1750
    public final void testRussian(){
1751
        String parseStr = "Cortusa turkestanica Losinsk. in Тр. Бот. инст. Aкад. наук СССР, сер. 1, 3: 239. 1936";
1752
        INonViralName name = parser.parseReferencedName(parseStr);
1753
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1754
        Reference nomRef = name.getNomenclaturalReference();
1755
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1756

    
1757
        assertEquals(ReferenceType.Article, nomRef.getType());
1758
        assertEquals(name.getNomenclaturalMicroReference(), "239");
1759
        assertEquals("Тр. Бот. инст. Aкад. наук СССР", nomRef.getInJournal().getAbbrevTitle());
1760
        assertEquals("сер. 1", nomRef.getSeriesPart());
1761
    }
1762

    
1763
    @Test
1764
    public final void testDetails(){
1765
        //s.p.
1766
        String parseStr = "Xiphion filifolium var. latifolium Baker, Gard. Chron. 1876: s.p.. 1876";
1767
        INonViralName name = parser.parseReferencedName(parseStr);
1768
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1769
        Reference nomRef = name.getNomenclaturalReference();
1770
        assertEquals(ReferenceType.Book, nomRef.getType());
1771
        assertEquals(name.getNomenclaturalMicroReference(), "s.p.");
1772

    
1773
        //roman
1774
        parseStr = "Ophrys lutea subsp. pseudospeculum (DC.) Kergu\u00e9len, Collect. Partim. Nat. 8: xv. 1993";
1775
        name = parser.parseReferencedName(parseStr);
1776
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1777
        nomRef = name.getNomenclaturalReference();
1778
        assertEquals(ReferenceType.Book, nomRef.getType());
1779
        assertEquals(name.getNomenclaturalMicroReference(), "xv");
1780

    
1781
        //n. 1
1782
        parseStr = "Olea gallica Mill., Gard. Dict. ed. 8: n. 1. 1768";
1783
        name = parser.parseReferencedName(parseStr);
1784
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1785
        nomRef = name.getNomenclaturalReference();
1786
        assertEquals(ReferenceType.Book, nomRef.getType());
1787
        assertEquals(name.getNomenclaturalMicroReference(), "n. 1");
1788

    
1789
        parseStr = "Lavandula canariensis Mill., Gard. Dict. ed. 8: Lavandula no. 4. 1768";
1790
        name = parser.parseReferencedName(parseStr);
1791
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1792
        nomRef = name.getNomenclaturalReference();
1793
        assertEquals(ReferenceType.Book, nomRef.getType());
1794
        assertEquals(name.getNomenclaturalMicroReference(), "Lavandula no. 4");
1795

    
1796
        parseStr = "Aceras anthropomorphum (Pers.) Sm. in Rees, Cycl. 39(1): Aceras n. 2. 1818";
1797
        name = parser.parseReferencedName(parseStr);
1798
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1799
        nomRef = name.getNomenclaturalReference();
1800
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1801
        assertEquals(name.getNomenclaturalMicroReference(), "Aceras n. 2");
1802

    
1803
        parseStr = "Chlorolepis Nutt. in Trans. Amer. Philos. Soc., n.s., 7: errata. 1841";
1804
        name = parser.parseReferencedName(parseStr);
1805
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1806
        nomRef = name.getNomenclaturalReference();
1807
        assertEquals(ReferenceType.Article, nomRef.getType());
1808
        assertEquals(name.getNomenclaturalMicroReference(), "errata");
1809

    
1810
        parseStr = "Yermoloffia B\u00e9l., Voy. Indes Or.: t. s.n.. 1846";
1811
        name = parser.parseReferencedName(parseStr);
1812
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1813
        nomRef = name.getNomenclaturalReference();
1814
        assertEquals(ReferenceType.Book, nomRef.getType());
1815
        assertEquals(name.getNomenclaturalMicroReference(), "t. s.n.");
1816

    
1817
        parseStr = "Gagea mauritanica Durieu, Expl. Sci. Alg\u00e9rie, Atlas: t. 45bis, f. 4. 1850";
1818
        name = parser.parseReferencedName(parseStr);
1819
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1820
        nomRef = name.getNomenclaturalReference();
1821
        assertEquals(ReferenceType.Book, nomRef.getType());
1822
        assertEquals(name.getNomenclaturalMicroReference(), "t. 45bis, f. 4");
1823

    
1824
        parseStr = "Orchis latifolia f. blyttii Rchb. f. in Reichenbach, Icon. Fl. Germ. Helv. 13-14: 60, t. 59, f. III. 1851";
1825
        name = parser.parseReferencedName(parseStr);
1826
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1827
        nomRef = name.getNomenclaturalReference();
1828
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1829
        assertEquals(name.getNomenclaturalMicroReference(), "60, t. 59, f. III");
1830

    
1831
        parseStr = "Ephedra alata var. decaisnei Stapf in Denkschr. Kaiserl. Akad. Wiss., Wien. Math.-Naturwiss. Kl. 56(2): t. 1/1. 1889";
1832
        name = parser.parseReferencedName(parseStr);
1833
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1834
        nomRef = name.getNomenclaturalReference();
1835
        assertEquals(ReferenceType.Article, nomRef.getType());
1836
        assertEquals(name.getNomenclaturalMicroReference(), "t. 1/1");
1837
    }
1838

    
1839
    @Test
1840
    public final void testEditionVolumeSeries(){
1841
        //ed. 2, 2(1)
1842
        String parseStr = "Sieberia albida (L.) Spreng., Anleit. Kenntn. Gew., ed. 2, 2(1): 282. 1817";
1843
        INonViralName name = parser.parseReferencedName(parseStr);
1844
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1845
        Reference nomRef = name.getNomenclaturalReference();
1846
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1847
        assertEquals(ReferenceType.Book, nomRef.getType());
1848
        assertEquals("2", nomRef.getEdition());
1849
        assertEquals("2(1)", nomRef.getVolume());
1850

    
1851
        parseStr = "Gagea glacialis var. joannis (Grossh.) Grossh., Fl. Kavkaza, ed. 2, 2: 105. 1940";
1852
        name = parser.parseReferencedName(parseStr);
1853
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1854
        nomRef = name.getNomenclaturalReference();
1855
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1856
        assertEquals(ReferenceType.Book, nomRef.getType());
1857
        assertEquals("2", nomRef.getEdition());
1858
        assertEquals("2", nomRef.getVolume());
1859

    
1860
        //14-15
1861
        parseStr = "Semele gayae (Webb & Berthel.) Svent. & Kunkel, Cuad. Bot. Canaria 14-15: 81. 1972";
1862
        name = parser.parseReferencedName(parseStr);
1863
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1864
        nomRef = name.getNomenclaturalReference();
1865
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1866
        assertEquals(ReferenceType.Book, nomRef.getType());
1867
        assertEquals("14-15", nomRef.getVolume());
1868

    
1869
        //35-37(2)
1870
        parseStr = "Lavandula multifida var. heterotricha Sauvage in Bull. Soc. Sci. Nat. Maroc 35-37(2): 392. 1947";
1871
        name = parser.parseReferencedName(parseStr);
1872
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1873
        nomRef = name.getNomenclaturalReference();
1874
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1875
        assertEquals(ReferenceType.Article, nomRef.getType());
1876
        assertNull(nomRef.getEdition());
1877
        assertEquals("35-37(2)", nomRef.getVolume());
1878

    
1879
        //Sér. 7
1880
        parseStr = "Oxynepeta involucrata Bunge, M\u00E9m. Acad. Imp. Sci. Saint P\u00E9tersbourg, S\u00E9r. 7, 21(1): 59. 1878";
1881
        name = parser.parseReferencedName(parseStr);
1882
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1883
        nomRef = name.getNomenclaturalReference();
1884
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1885
        assertEquals(ReferenceType.Book, nomRef.getType());
1886
        assertNull(nomRef.getEdition());
1887
        assertEquals("21(1)", nomRef.getVolume());
1888
        //Currently we do not put the series part into the series field, this may change in future
1889
//        assertEquals("Sér. 7", nomRef.getSeriesPart());
1890

    
1891
        //Suppl. 1
1892
        parseStr = "Dissorhynchium Schauer, Nov. Actorum Acad. Caes. Leop.-Carol. Nat. Cur. 19(Suppl. 1): 434. 1843";
1893
        name = parser.parseReferencedName(parseStr);
1894
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1895
        nomRef = name.getNomenclaturalReference();
1896
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1897
        assertEquals(ReferenceType.Book, nomRef.getType());
1898
        assertNull(nomRef.getEdition());
1899
        assertEquals("19(Suppl. 1)", nomRef.getVolume());
1900

    
1901
        //54*B*
1902
        parseStr = "Thymus chaubardii var. boeoticus (Heinr. Braun) Ronniger in Beih. Bot. Centralbl. 54B: 662. 1936";
1903
        name = parser.parseReferencedName(parseStr);
1904
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1905
        nomRef = name.getNomenclaturalReference();
1906
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1907
        assertEquals(ReferenceType.Article, nomRef.getType());
1908
        assertNull(nomRef.getEdition());
1909
        assertEquals("54B", nomRef.getVolume());
1910

    
1911

    
1912
        //1, Erg.
1913
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.volume);
1914
        Matcher matcher = seriesPattern.matcher("12(1, Erg.)");
1915
        Assert.assertTrue("12(1, Erg.) should match", matcher.matches());
1916

    
1917
        parseStr = "Scilla amethystina Vis. in Flora Abt Awer Ser 12(1, Erg.): 11. 1829";
1918
        name = parser.parseReferencedName(parseStr);
1919
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1920
        nomRef = name.getNomenclaturalReference();
1921
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1922
        assertEquals(ReferenceType.Article, nomRef.getType());
1923
        assertNull(nomRef.getEdition());
1924
        assertEquals("12(1, Erg.)", nomRef.getVolume());
1925

    
1926
        // jubilee ed.
1927
        parseStr = "Orchis sambucina var. bracteata (M. Schulze) Harz, Fl. Deutschl., jubilee ed., 4: 271. 1895";
1928
        name = parser.parseReferencedName(parseStr);
1929
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1930
        nomRef = name.getNomenclaturalReference();
1931
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1932
        assertEquals(ReferenceType.Book, nomRef.getType());
1933
        assertEquals("jubilee ed.",nomRef.getEdition());
1934
        assertEquals("4", nomRef.getVolume());
1935
        assertEquals(parseStr, name.getFullTitleCache());
1936

    
1937
        //nouv. ed.
1938
        parseStr = "Fraxinus polemonifolia Poir. in Duhamel du Monceau, Trait\u00E9 Arbr. Arbust., nouv. ed., 4: 66. 1809";
1939
        name = parser.parseReferencedName(parseStr);
1940
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1941
        nomRef = name.getNomenclaturalReference();
1942
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1943
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1944
        assertEquals("nouv. ed.",nomRef.getInReference().getEdition());
1945
        assertEquals("4", nomRef.getInReference().getVolume());
1946
        assertEquals(parseStr, name.getFullTitleCache());
1947

    
1948
        //ed. 3B
1949
        parseStr = "Juncus supinus var. kochii (F. W. Schultz) Syme in Smith, Engl. Bot., ed. 3B, 10: 33. 1870";
1950
        name = parser.parseReferencedName(parseStr);
1951
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1952
        nomRef = name.getNomenclaturalReference();
1953
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1954
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1955
        //maybe we remove ed. for this case in future
1956
        assertEquals("ed. 3B",nomRef.getInReference().getEdition());
1957
        assertEquals("10", nomRef.getInReference().getVolume());
1958
        assertEquals(parseStr, name.getFullTitleCache());
1959

    
1960
        //ed. 15 bis
1961
        parseStr = "Solanum persicum Willd. ex Roem. & Schult., Syst. Veg., ed. 15 bis, 4: 662. 1819";
1962
        name = parser.parseReferencedName(parseStr);
1963
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1964
        nomRef = name.getNomenclaturalReference();
1965
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1966
        assertEquals(ReferenceType.Book, nomRef.getType());
1967
        //maybe we remove ed. for this case in future
1968
        assertEquals("ed. 15 bis",nomRef.getEdition());
1969
        assertEquals("4", nomRef.getVolume());
1970
        assertEquals(parseStr, name.getFullTitleCache());
1971

    
1972

    
1973
//        Epipactis helleborine subsp. ohwii (Fukuy.) H. J. Su in Fl. Taiwan, ed. 2, 5: 861. 2000
1974
    }
1975

    
1976
    @Test
1977
    public final void testTitleBrackets(){
1978
        //Bot. Zhurn. (Moscow & Leningrad)
1979
        String parseStr = "Juncus subcompressus Zakirov & Novopokr. in Bot. Zhurn. (Moscow & Leningrad) 36(1): 77. 1951";
1980
        TaxonName name = parser.parseReferencedName(parseStr);
1981
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1982
        Reference nomRef = name.getNomenclaturalReference();
1983
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1984
        assertEquals(ReferenceType.Article, nomRef.getType());
1985
        assertEquals("Bot. Zhurn. (Moscow & Leningrad)", nomRef.getInReference().getAbbrevTitle());
1986
        assertNull(nomRef.getEdition());
1987
        assertEquals("36(1)", nomRef.getVolume());
1988
    }
1989

    
1990
    @Test
1991
    public final void testTitleSpecials(){
1992
        //Pt. 2  (currently handled as series part, may change in future
1993
        String parseStr = "Iris pumila subsp. sintenisiiformis Prod\u00E1n in Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat. 27: 89. 1941";
1994
        TaxonName name = parser.parseReferencedName(parseStr);
1995
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1996
        Reference nomRef = name.getNomenclaturalReference();
1997
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1998
        assertEquals(ReferenceType.Article, nomRef.getType());
1999
        assertEquals("Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat.", nomRef.getInReference().getAbbrevTitle());
2000
        assertNull(nomRef.getEdition());
2001
        assertEquals("27", nomRef.getVolume());
2002

    
2003
        //same as Pt. 2, "Sect. xx" handled as series part but may change
2004
        parseStr = "Quercus boissieri var. microphylla (A. Camus) Zohary in Bull. Res. Council Israel, Sect. D, Bot. 9: 169. 1961";
2005
        name = parser.parseReferencedName(parseStr);
2006
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2007
        nomRef = name.getNomenclaturalReference();
2008
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2009
        assertEquals(ReferenceType.Article, nomRef.getType());
2010
        assertEquals("Bull. Res. Council Israel, Sect. D, Bot.", nomRef.getInReference().getAbbrevTitle());
2011
        assertNull(nomRef.getEdition());
2012
        assertEquals("9", nomRef.getVolume());
2013

    
2014
        //see above
2015
        parseStr = "Fimbristylis dichotoma var. annua (All.) T. Koyama in J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot. 8: 111. 1961";
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.Article, nomRef.getType());
2021
        assertEquals("J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot.", nomRef.getInReference().getAbbrevTitle());
2022
        assertNull(nomRef.getEdition());
2023
        assertEquals("8", nomRef.getVolume());
2024

    
2025

    
2026
        // "- "
2027
        parseStr = "Theresia tulipilfoia (M. Bieb.) Klatt in Hamburger Garten- Blumenzeitung 16: 438. 1860";
2028
        name = parser.parseReferencedName(parseStr);
2029
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2030
        nomRef = name.getNomenclaturalReference();
2031
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2032
        assertEquals(ReferenceType.Article, nomRef.getType());
2033
        assertEquals("Hamburger Garten- Blumenzeitung", nomRef.getInReference().getAbbrevTitle());
2034
        assertNull(nomRef.getEdition());
2035
        assertEquals("16", nomRef.getVolume());
2036

    
2037
        parseStr = "Hyssopus officinalis var. pilifer Pant. in Verh. Vereins Natur- Heilk. Presburg, n.s., 2: 61. 1874";
2038
        name = parser.parseReferencedName(parseStr);
2039
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2040
        nomRef = name.getNomenclaturalReference();
2041
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2042
        assertEquals(ReferenceType.Article, nomRef.getType());
2043
        //, n.s., is not necessarily part of the title in future
2044
        assertEquals("Verh. Vereins Natur- Heilk. Presburg", nomRef.getInReference().getAbbrevTitle());
2045
        assertNull(nomRef.getEdition());
2046
        assertEquals("n.s.", nomRef.getSeriesPart());
2047
        assertEquals("2", nomRef.getVolume());
2048

    
2049
          //Note: space in E+M, no space in IPNI; is it really a book?
2050
        parseStr = "Amaryllis dubia Houtt., Handl. Pl.- Kruidk. 12: 181. 1780";
2051
        name = parser.parseReferencedName(parseStr);
2052
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2053
        nomRef = name.getNomenclaturalReference();
2054
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2055
        assertEquals(ReferenceType.Book, nomRef.getType());
2056
        assertEquals("Handl. Pl.- Kruidk.", nomRef.getAbbrevTitle());
2057
        assertNull(nomRef.getEdition());
2058
        assertEquals("12", nomRef.getVolume());
2059

    
2060
        // "..."
2061
        parseStr = "Chamaesyce biramensis (Urb.) Alain in Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\" 11: 12. 1952";
2062
        name = parser.parseReferencedName(parseStr);
2063
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2064
        nomRef = name.getNomenclaturalReference();
2065
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2066
        assertEquals(ReferenceType.Article, nomRef.getType());
2067
        assertEquals("Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\"", nomRef.getInReference().getAbbrevTitle());
2068
        assertNull(nomRef.getEdition());
2069
        assertEquals("11", nomRef.getVolume());
2070

    
2071
        //' & '
2072
        parseStr = "Mannaphorus Raf. in Amer. Monthly Mag. & Crit. Rev. 1: 175. 1818";
2073
        name = parser.parseReferencedName(parseStr);
2074
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2075
        nomRef = name.getNomenclaturalReference();
2076
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2077
        assertEquals(ReferenceType.Article, nomRef.getType());
2078
        assertEquals("Amer. Monthly Mag. & Crit. Rev.", nomRef.getInReference().getAbbrevTitle());
2079
        assertNull(nomRef.getEdition());
2080
        assertEquals("1", nomRef.getVolume());
2081

    
2082
        //only for debugging
2083
        boolean  matches;
2084
        matches = "Flo & Amer. Fauna. Ab.".matches (NonViralNameParserImplRegExBase.referenceTitleFirstPart + "*");
2085
        Assert.assertTrue("referenceTitleFirstPart", matches);
2086

    
2087
        matches = "Fl. Amer. & Fauna. Ab. 101".matches (NonViralNameParserImplRegExBase.pSoftArticleReference);
2088
        Assert.assertTrue("pSoftArticleReference", matches);
2089
        //only for debugging end
2090

    
2091
        parseStr = "Corallorhiza trifida subsp. virescens (Drejer) L\u00F8jtnant in Fl. & Fauna (Esbjerg) 101: 71. 1996";
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
        assertEquals("Fl. & Fauna (Esbjerg)", nomRef.getInReference().getAbbrevTitle());
2098
        assertNull(nomRef.getEdition());
2099
        assertEquals("101", nomRef.getVolume());
2100

    
2101
        parseStr = "Crocus isauricus Siehe ex Bowles, Handb. Crocus & Colch.: 126. 1924";
2102
        name = parser.parseReferencedName(parseStr);
2103
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2104
        nomRef = name.getNomenclaturalReference();
2105
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2106
        assertEquals(ReferenceType.Book, nomRef.getType());
2107
        assertEquals("Handb. Crocus & Colch.", nomRef.getAbbrevTitle());
2108
        assertNull(nomRef.getEdition());
2109
        assertNull(nomRef.getVolume());
2110

    
2111
        parseStr = "Ornithogalum bifolium (L.) Neck. in Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat. 2: 461. 1770";
2112
        name = parser.parseReferencedName(parseStr);
2113
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2114
        nomRef = name.getNomenclaturalReference();
2115
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2116
        assertEquals(ReferenceType.Article, nomRef.getType());
2117
        assertEquals("Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat.", nomRef.getInReference().getAbbrevTitle());
2118
        assertNull(nomRef.getEdition());
2119
        assertEquals("2", nomRef.getVolume());
2120

    
2121
    }
2122

    
2123
    @Test
2124
    public final void testArticlePattern(){
2125
        Pattern articlePattern = Pattern.compile(NonViralNameParserImplRegExBase.pArticleReference);
2126
        Matcher matcher = articlePattern.matcher("Acta Bot. Hung. 46 (1-2)");
2127
        Assert.assertTrue("", matcher.matches());
2128
        matcher = articlePattern.matcher("Nova Guinea Bla 9");
2129
        Assert.assertTrue("", matcher.matches());
2130
        matcher = articlePattern.matcher("Nova Guinea Bla , n.s., 9");
2131
        Assert.assertTrue("", matcher.matches());
2132
    }
2133

    
2134

    
2135
    @Test
2136
    public final void testSeriesPart(){
2137
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.pSeriesPart);
2138
        Matcher matcher = seriesPattern.matcher(", ser. 2,");
2139
        Assert.assertTrue("", matcher.matches());
2140

    
2141
        matcher = seriesPattern.matcher("n.s.");
2142
        Assert.assertTrue("", matcher.matches());
2143

    
2144
//        matcher = seriesPattern.matcher("a.s.");
2145
//        Assert.assertTrue("", matcher.matches());
2146

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

    
2151
        matcher = seriesPattern.matcher("Ser. C");
2152
        Assert.assertTrue("", matcher.matches());
2153

    
2154
        matcher = seriesPattern.matcher("S\u00E9r. B 1");
2155
        Assert.assertTrue("", matcher.matches());
2156

    
2157
        matcher = seriesPattern.matcher("Jerusalem Ser.");
2158
        Assert.assertTrue("", matcher.matches());
2159

    
2160
        matcher = seriesPattern.matcher("nov. Ser.");
2161
        Assert.assertTrue("", matcher.matches());
2162
    }
2163

    
2164
    @Test
2165
    public final void testFullTeams() {
2166
        logger.warn("Not yet implemented"); // TODO
2167
    }
2168

    
2169
    @Test
2170
    public final void testParseAuthorsTaxonNameString() throws StringNotParsableException {
2171
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
2172
        parser.parseAuthors(nvn, "Eckweiler & ten Hagen, 2003");
2173
        Team team = (Team)nvn.getCombinationAuthorship();
2174
        Assert.assertNotNull("Comb. author must not be null", team);
2175
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
2176
        Assert.assertEquals("Second member must be 'ten Hagen'", "ten Hagen", team.getTeamMembers().get(1).getTitleCache());
2177

    
2178
        //Crosson du Cormier, 1964
2179
        IZoologicalName zooName = TaxonNameFactory.NewZoologicalInstance(null);
2180
        parser.parseAuthors(zooName, "Crosson du Cormier, 1964");
2181
        Person person = (Person)zooName.getCombinationAuthorship();
2182
        Assert.assertNotNull("Comb. author must not be null", person);
2183
        Assert.assertEquals("Persons title must be 'Crosson du Cormier'", "Crosson du Cormier", person.getTitleCache());
2184
        Assert.assertEquals("Year must be 1964", Integer.valueOf(1964), zooName.getPublicationYear() );
2185

    
2186
        //(van der Hoeven, 1839)
2187
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2188
        parser.parseAuthors(zooName, "(van der Hoeven, 1839)");
2189
        Assert.assertNull("Combination author must be null", zooName.getCombinationAuthorship());
2190
        person = (Person)zooName.getBasionymAuthorship();
2191
        Assert.assertNotNull("Basionym author must not be null", person);
2192
        Assert.assertEquals("Persons title must be 'van der Hoeven'", "van der Hoeven", person.getTitleCache());
2193
        Assert.assertEquals("Year must be 1839", Integer.valueOf(1839), zooName.getOriginalPublicationYear() );
2194

    
2195
        //le Doux, 1931
2196
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2197
        parser.parseAuthors(zooName, "le Doux, 1931");
2198
        person = (Person)zooName.getCombinationAuthorship();
2199
        Assert.assertNotNull("Comb. author must not be null", person);
2200
        Assert.assertEquals("Persons title must be 'le Doux'", "le Doux", person.getTitleCache());
2201
        Assert.assertEquals("Year must be 1931", Integer.valueOf(1931), zooName.getPublicationYear() );
2202

    
2203

    
2204
    }
2205

    
2206
    @Test  //#4764
2207
    public void testParseSection(){
2208
        //this test does not really test problematic cases where sect.idInVoc = "sect." instead of "sect.(bot.)"
2209
        //however, by changing the csv file entry to sect. just for testing it can be used as a functional test
2210
        String sectionNameStr = "Taraxacum sect. Testtaxa M\u00fcller, Incredible Taxa: 12. 2016";
2211
        INonViralName sectionName = parser.parseReferencedName(sectionNameStr, NomenclaturalCode.ICNAFP, null);
2212
        int parsingProblem = sectionName.getParsingProblem();
2213
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
2214
        Rank rank = sectionName.getRank();
2215
        Assert.assertEquals("", Rank.SECTION_BOTANY(), rank  );
2216
    }
2217

    
2218
    //#6577
2219
    @Test
2220
    public final void testParseSpNov(){
2221
        //Canabio, issue with space
2222
        INonViralName name = parser.parseFullName("Iresine sp. nov. 1");
2223
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2224
        Assert.assertEquals("sp. nov. 1", name.getSpecificEpithet());
2225

    
2226
        name = parser.parseFullName("Gomphichis sp. 22");
2227
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2228
        Assert.assertEquals("sp. 22", name.getSpecificEpithet());
2229

    
2230
        name = parser.parseFullName("Phleum sp. nov.");
2231
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2232
        Assert.assertEquals("sp. nov.", name.getSpecificEpithet());
2233

    
2234
        name = parser.parseFullName("Phleum sp.");
2235
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2236
        Assert.assertEquals("sp.", name.getSpecificEpithet());
2237

    
2238
    }
2239

    
2240

    
2241
    @Test  //#5072
2242
    public final void testLongRunningParsingCapitals(){
2243
        DateTime start = DateTime.now();
2244
        String nameStr = "Nazeris fujianensis JIAYAO HU, LIZHEN LI, MEIJUN ZHAO,2010";  //name from CoL that created problems
2245
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICZN, null);
2246
        DateTime end = DateTime.now();
2247
        Duration duration = new Duration(start, end);
2248
        long seconds = duration.getStandardSeconds();
2249
        //this is the critical part of the test that must not be changed
2250
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2251

    
2252
    }
2253

    
2254
    @Test  //#5072
2255
    //http://www.regular-expressions.info/catastrophic.html
2256
    public final void testLongRunningParsing(){
2257

    
2258
        //name only
2259
        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";
2260
        DateTime start = DateTime.now();
2261
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2262
        DateTime end = DateTime.now();
2263
        Duration duration = new Duration(start, end);
2264
        long seconds = duration.getStandardSeconds();
2265
        //this is the critical part of the test that must not be changed
2266
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2267
        //the following may be discussed
2268
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2269

    
2270

    
2271
        //with reference
2272
        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.";
2273
        start = DateTime.now();
2274
        name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2275
        end = DateTime.now();
2276
        duration = new Duration(start, end);
2277
        seconds = duration.getStandardSeconds();
2278
        //this is the critical part of the test that must not be changed
2279
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2280
        //the following may be discussed
2281
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2282
    }
2283

    
2284
    @Test  //#5072
2285
    public final void testLongRunningParsingAuthors(){
2286
        //http://www.regular-expressions.info/catastrophic.html
2287
        //
2288
        //Länge des Nachnamens macht keinen Unterschied
2289
        //Anzahl der "AuthorParts scheint entscheidend
2290
        // & am Ende macht es langsamger (16s), als nur ","(6s))
2291

    
2292
        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";
2293
        TeamOrPersonBase[] authorArray = new TeamOrPersonBase[4];
2294
        try {
2295
            DateTime start = DateTime.now();
2296
            parser.fullAuthors(authorStr, authorArray, new Integer[]{1800, null, null, null}, NomenclaturalCode.ICNAFP);
2297
            DateTime end = DateTime.now();
2298
            Duration duration = new Duration(start, end);
2299
            long seconds = duration.getStandardSeconds();
2300
//            System.out.println(seconds);
2301
            //this is the critical part of the test that must not be changed
2302
            Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2303
        } catch (StringNotParsableException e) {
2304
            e.printStackTrace();
2305
            Assert.fail("Authors should be parsable");
2306
        }
2307

    
2308
    }
2309

    
2310

    
2311
    /**
2312
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#AuthorshipAndEx(java.lang.String)}.
2313
     */
2314
    @Test
2315
    public final void testAuthorshipAndEx() {
2316
        logger.warn("Not yet implemented"); // TODO
2317
    }
2318

    
2319
    /**
2320
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#Authorship(java.lang.String)}.
2321
     */
2322
    @Test
2323
    public final void testAuthorship() {
2324
        logger.warn("Not yet implemented"); // TODO
2325
    }
2326

    
2327
    /**
2328
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseCultivar(java.lang.String)}.
2329
     */
2330
    @Test
2331
    public final void testParseCultivar() {
2332
        logger.warn("Not yet implemented"); // TODO
2333
    }
2334

    
2335
    @Test
2336
    public final void testNomenclaturalStatus() {
2337
        IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY(), "Acanthopale", null, null, null, null, null, null, null);
2338
        name.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ALTERNATIVE()));
2339
        IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
2340
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2341
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2342
        Assert.assertEquals("Title cache should be same. No duplication of nom. status should take place", name.getFullTitleCache(), name2.getFullTitleCache());
2343
    }
2344

    
2345
    @Test
2346
    public final void testSpecificAuthors(){
2347
        //McVaugh
2348
        INonViralName name = parser.parseFullName("Psidium longipes var. orbiculare (O.Berg) McVaugh");
2349
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2350
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2351
        assertEquals( "McVaugh", combinationAuthor.getNomenclaturalTitle());
2352
        TeamOrPersonBase<?> basionymAuthor = name.getBasionymAuthorship();
2353
        assertEquals( "O.Berg", basionymAuthor.getNomenclaturalTitle());
2354

    
2355
//      Campanula rhodensis A. DC.
2356

    
2357
    }
2358

    
2359
    @Test
2360
    public final void testBookSectionAuthors(){
2361
        INonViralName name;
2362
        Reference nomRef;
2363
        String title;
2364
        String str;
2365

    
2366
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2367
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2368
        name = parser.parseReferencedName(str);
2369
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2370
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2371
        assertEquals( "Asch. & Schweinf.", combinationAuthor.getNomenclaturalTitle());
2372
        nomRef = name.getNomenclaturalReference();
2373
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2374
        assertEquals( "Barbey-Boissier & Barbey", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2375
        title = nomRef.getInReference().getAbbrevTitle();
2376
        assertEquals( "Herb. Levant", title);
2377

    
2378
        name = parser.parseReferencedName("Luzula multiflora subsp. pallescens (Sw.) Reichg. in Van Ooststroom & al., Fl. Neerl. 1: 208. 1964");
2379
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2380
        assertEquals( "Reichg.", name.getCombinationAuthorship().getNomenclaturalTitle());
2381
        nomRef = name.getNomenclaturalReference();
2382
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2383
        assertEquals( "Van Ooststroom & al.", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2384
        title = nomRef.getInReference().getAbbrevTitle();
2385
        assertEquals( "Fl. Neerl.", title);
2386

    
2387
        str = "Salvia pratensis var. albiflora T. Durand in De Wildeman & Durand, Prodr. Fl. Belg. 3: 663. 1899";
2388
        name = parser.parseReferencedName(str);
2389
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2390
        assertEquals( "T. Durand", name.getCombinationAuthorship().getNomenclaturalTitle());
2391
        nomRef = name.getNomenclaturalReference();
2392
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2393
        assertEquals( "De Wildeman & Durand", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2394
        title = nomRef.getInReference().getAbbrevTitle();
2395
        assertEquals( "Prodr. Fl. Belg.", title);
2396

    
2397
        str = "Bravoa Lex. in La Llave & Lexarza, Nov. Veg. Desc. 1: 6. 1824";
2398
        name = parser.parseReferencedName(str);
2399
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2400
        assertEquals( "Lex.", name.getCombinationAuthorship().getNomenclaturalTitle());
2401
        nomRef = name.getNomenclaturalReference();
2402
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2403
        assertEquals( "La Llave & Lexarza", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2404
        title = nomRef.getInReference().getAbbrevTitle();
2405
        assertEquals( "Nov. Veg. Desc.", title);
2406

    
2407
        str = "Thymus trachselianus var. vallicola Heinr. Braun in Dalla Torre & Sarnthein, Fl. Tirol 6(3): 204. 1912";
2408
        name = parser.parseReferencedName(str);
2409
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2410
        nomRef = name.getNomenclaturalReference();
2411
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2412
        assertEquals( "Dalla Torre & Sarnthein", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2413
        title = nomRef.getInReference().getAbbrevTitle();
2414
        assertEquals( "Fl. Tirol", title);
2415

    
2416
        //see #openIssues
2417
//        str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2418
//        name = parser.parseReferencedName(str);
2419
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2420
//        nomRef = name.getNomenclaturalReference();
2421
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2422
//        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2423
//        title = nomRef.getInReference().getAbbrevTitle();
2424
//        assertEquals( "Nova Fl. Portugal", title);
2425
//
2426
//        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2427
//        name = parser.parseReferencedName(str);
2428
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2429
//        nomRef = name.getNomenclaturalReference();
2430
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2431
//        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2432
//        title = nomRef.getInReference().getAbbrevTitle();
2433
//        assertEquals( "Mount. Fl. Greece", title);
2434

    
2435
    }
2436

    
2437
    @Test
2438
    public final void testDatePublished(){
2439

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

    
2446
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. 4 Apr 1977");
2447
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2448
        nomRef = name.getNomenclaturalReference();
2449
        assertEquals(ReferenceType.Article, nomRef.getType());
2450
        assertEquals("4 Apr 1977", nomRef.getDatePublished().toString());
2451
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getStartMonth());
2452

    
2453
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. Feb-Apr 1977");
2454
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2455
        nomRef = name.getNomenclaturalReference();
2456
        assertEquals(ReferenceType.Article, nomRef.getType());
2457
        assertEquals("Feb"+SEP+"Apr 1977", nomRef.getDatePublished().toString());
2458
        assertEquals(Integer.valueOf(2), nomRef.getDatePublished().getStartMonth());
2459
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getEndMonth());
2460
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getStartYear());
2461
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getEndYear());
2462
        assertNull(nomRef.getDatePublished().getStartDay());
2463
        assertNull(nomRef.getDatePublished().getEndDay());
2464
    }
2465

    
2466

    
2467
    @Test
2468
    public final void testExistingProblems(){
2469
        //Canabio, issue with space
2470
        INonViralName name = parser.parseReferencedName("Machaonia erythrocarpa var. hondurensis (Standl.) Borhidi"
2471
                + " in Acta Bot. Hung. 46 (1-2): 30. 2004");
2472
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2473
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2474
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2475
        Reference nomRef = name.getNomenclaturalReference();
2476
        assertEquals(ReferenceType.Article, nomRef.getType());
2477
        assertEquals("46 (1-2)", nomRef.getVolume());
2478

    
2479
        //Canabio, detail with fig.
2480
        name = parser.parseReferencedName("Didymaea floribunda Rzed."
2481
                + " in Bol. Soc. Bot. Mex. 44: 72, fig. 1. 1983");
2482
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2483
        combinationAuthor = name.getCombinationAuthorship();
2484
        assertEquals( "Rzed.", combinationAuthor.getNomenclaturalTitle());
2485
        nomRef = name.getNomenclaturalReference();
2486
        assertEquals(ReferenceType.Article, nomRef.getType());
2487
        assertEquals("44", nomRef.getVolume());
2488
        assertEquals("72, fig. 1", name.getNomenclaturalMicroReference());
2489

    
2490
        //fig with a-c and without dot
2491
        name = parser.parseReferencedName("Deppea guerrerensis Dwyer & Lorence"
2492
                + " in Allertonia 4: 428. fig 4a-c. 1988");  //
2493
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2494
        combinationAuthor = name.getCombinationAuthorship();
2495
        assertEquals( "Dwyer & Lorence", combinationAuthor.getNomenclaturalTitle());
2496
        nomRef = name.getNomenclaturalReference();
2497
        assertEquals(ReferenceType.Article, nomRef.getType());
2498
        assertEquals("4", nomRef.getVolume());
2499
        assertEquals("428. fig 4a-c", name.getNomenclaturalMicroReference());
2500

    
2501
        //issue with EN_DASH (3–4)
2502
        name = parser.parseReferencedName("Arachnothryx tacanensis (Lundell) Borhidi"
2503
              + " in Acta Bot. Hung. 33 (3" + UTF8.EN_DASH + "4): 303. 1987");
2504
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2505
        combinationAuthor = name.getCombinationAuthorship();
2506
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2507
        nomRef = name.getNomenclaturalReference();
2508
        assertEquals(ReferenceType.Article, nomRef.getType());
2509
        assertEquals("33 (3" + UTF8.EN_DASH + "4)", nomRef.getVolume());
2510
        assertEquals("303", name.getNomenclaturalMicroReference());
2511

    
2512
        //fig with f.
2513
        name = parser.parseReferencedName("Stenotis Terrell"
2514
                + " in Sida 19(4): 901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2. 2001");
2515
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2516
        combinationAuthor = name.getCombinationAuthorship();
2517
        assertEquals( "Terrell", combinationAuthor.getNomenclaturalTitle());
2518
        nomRef = name.getNomenclaturalReference();
2519
        assertEquals(ReferenceType.Article, nomRef.getType());
2520
        assertEquals("19(4)", nomRef.getVolume());
2521
        assertEquals("901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2", name.getNomenclaturalMicroReference());
2522

    
2523
        //detail with figs
2524
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2525
                + " in Contr. Dudley Herb. 3: 75, figs 4-6. 1940");
2526
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2527
        combinationAuthor = name.getCombinationAuthorship();
2528
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitle());
2529
        nomRef = name.getNomenclaturalReference();
2530
        assertEquals(ReferenceType.Article, nomRef.getType());
2531
        assertEquals("3", nomRef.getVolume());
2532
        assertEquals("75, figs 4-6", name.getNomenclaturalMicroReference());
2533

    
2534
        //detail with pl. and figs
2535
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2536
                + " in Contr. Dudley Herb. 3: 75, pl. 19, figs 4-6. 1940");
2537
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2538
        combinationAuthor = name.getCombinationAuthorship();
2539
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitle());
2540
        nomRef = name.getNomenclaturalReference();
2541
        assertEquals(ReferenceType.Article, nomRef.getType());
2542
        assertEquals("3", nomRef.getVolume());
2543
        assertEquals("75, pl. 19, figs 4-6", name.getNomenclaturalMicroReference());
2544

    
2545
        //pl
2546
        name = parser.parseReferencedName("Carapichea  Aubl."
2547
                + " in Hist. Pl. Guiane 1: 167, pl. 64. 1775");
2548
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2549
        combinationAuthor = name.getCombinationAuthorship();
2550
        assertEquals( "Aubl.", combinationAuthor.getNomenclaturalTitle());
2551
        nomRef = name.getNomenclaturalReference();
2552
        assertEquals(ReferenceType.Article, nomRef.getType());
2553
        assertEquals("1", nomRef.getVolume());
2554
        assertEquals("167, pl. 64", name.getNomenclaturalMicroReference());
2555

    
2556
        //fig with ,
2557
        name = parser.parseReferencedName("Hoffmannia ixtlanensis Lorence"
2558
                + " in Novon 4: 121. fig. 2a, b. 1994");
2559
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2560
        combinationAuthor = name.getCombinationAuthorship();
2561
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitle());
2562
        nomRef = name.getNomenclaturalReference();
2563
        assertEquals(ReferenceType.Article, nomRef.getType());
2564
        assertEquals("4", nomRef.getVolume());
2565
        assertEquals("121. fig. 2a, b", name.getNomenclaturalMicroReference());
2566

    
2567
        //detail with , to number
2568
        name = parser.parseReferencedName("Deppea martinez-calderonii Lorence"
2569
                + " in Allertonia 4: 399. figs 1e, 2. 1988");
2570
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2571
        combinationAuthor = name.getCombinationAuthorship();
2572
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitle());
2573
        nomRef = name.getNomenclaturalReference();
2574
        assertEquals(ReferenceType.Article, nomRef.getType());
2575
        assertEquals("4", nomRef.getVolume());
2576
        assertEquals("399. figs 1e, 2", name.getNomenclaturalMicroReference());
2577

    
2578
        //(Suppl.)
2579
        name = parser.parseReferencedName("Manettia costaricensis  Wernham"
2580
                + " in J. Bot. 57(Suppl.): 38. 1919");
2581
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2582
        combinationAuthor = name.getCombinationAuthorship();
2583
        assertEquals( "Wernham", combinationAuthor.getNomenclaturalTitle());
2584
        nomRef = name.getNomenclaturalReference();
2585
        assertEquals(ReferenceType.Article, nomRef.getType());
2586
        assertEquals("57(Suppl.)", nomRef.getVolume());
2587
        assertEquals("38", name.getNomenclaturalMicroReference());
2588

    
2589
        //NY.
2590
        name = parser.parseReferencedName("Crusea psyllioides (Kunth) W.R. Anderson"
2591
                + " in Mem. NY. Bot. Gard. 22: 75. 1972");
2592
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2593
        combinationAuthor = name.getCombinationAuthorship();
2594
        assertEquals( "W.R. Anderson", combinationAuthor.getNomenclaturalTitle());
2595
        nomRef = name.getNomenclaturalReference();
2596
        assertEquals(ReferenceType.Article, nomRef.getType());
2597
        assertEquals("22", nomRef.getVolume());
2598
        assertEquals("75", name.getNomenclaturalMicroReference());
2599

    
2600
        //apostroph word in title
2601
        name = parser.parseReferencedName("Sabicea glabrescens Benth."
2602
                + " in Hooker's J. Bot. Kew Gard. Misc. 3: 219. 1841");
2603
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2604
        combinationAuthor = name.getCombinationAuthorship();
2605
        assertEquals( "Benth.", combinationAuthor.getNomenclaturalTitle());
2606
        nomRef = name.getNomenclaturalReference();
2607
        assertEquals(ReferenceType.Article, nomRef.getType());
2608
        assertEquals("3", nomRef.getVolume());
2609
        assertEquals("219", name.getNomenclaturalMicroReference());
2610

    
2611
        // place published e.g. (Hannover)
2612
        name = parser.parseReferencedName("Pittoniotis trichantha Griseb."
2613
                  + " in Bonplandia (Hannover) 6 (1): 8. 1858");
2614
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2615
        combinationAuthor = name.getCombinationAuthorship();
2616
        assertEquals( "Griseb.", combinationAuthor.getNomenclaturalTitle());
2617
        nomRef = name.getNomenclaturalReference();
2618
        assertEquals(ReferenceType.Article, nomRef.getType());
2619
        assertEquals("6 (1)", nomRef.getVolume());
2620
        assertEquals("8", name.getNomenclaturalMicroReference());
2621

    
2622
        //komplex / incorrect year without quotation marks
2623
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2624
                + " in Acta Bot. Hung. 29(1\u20134): 16, f. 1\u20132, t. 1-8. 1983 [1984]");
2625
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2626
        combinationAuthor = name.getCombinationAuthorship();
2627
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2628
        nomRef = name.getNomenclaturalReference();
2629
        assertEquals(ReferenceType.Article, nomRef.getType());
2630
        assertEquals("29(1\u20134)", nomRef.getVolume());
2631
        assertEquals("16, f. 1\u20132, t. 1-8", name.getNomenclaturalMicroReference());
2632
        assertEquals("1983 [1984]", nomRef.getDatePublishedString());
2633
//        assertEquals("1984", nomRef.getYear()); //was like this, but is not necessarily correct, see #7429
2634

    
2635
        //incorrect year with \u201e \u201f  (s. eu.etaxonomy.cdm.common.UTF8.ENGLISH_QUOT_START
2636
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2637
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \u201e1983\u201f [1984]");
2638
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2639
        combinationAuthor = name.getCombinationAuthorship();
2640
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2641
        nomRef = name.getNomenclaturalReference();
2642
        assertEquals(ReferenceType.Article, nomRef.getType());
2643
        assertEquals("29(1-4)", nomRef.getVolume());
2644
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2645
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2646
        assertEquals("1984", nomRef.getYear());
2647

    
2648
        //incorrect year with "
2649
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2650
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \"1983\" [1984]");
2651
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2652
        combinationAuthor = name.getCombinationAuthorship();
2653
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2654
        nomRef = name.getNomenclaturalReference();
2655
        assertEquals(ReferenceType.Article, nomRef.getType());
2656
        assertEquals("29(1-4)", nomRef.getVolume());
2657
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2658
        //changed from "1983" [1984] to 1984 ["1983"] after implementing #7429
2659
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2660
        assertEquals("1984", nomRef.getYear());
2661

    
2662
        //fig. a
2663
        name = parser.parseReferencedName("Psychotria capitata  Ruiz & Pav."
2664
                + " in Fl. Peruv. 2: 59, pl. 206, fig. a. 1799");
2665
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2666
        combinationAuthor = name.getCombinationAuthorship();
2667
        assertEquals( "Ruiz & Pav.", combinationAuthor.getNomenclaturalTitle());
2668
        nomRef = name.getNomenclaturalReference();
2669
        assertEquals(ReferenceType.Article, nomRef.getType());
2670
        assertEquals("2", nomRef.getVolume());
2671
        assertEquals("59, pl. 206, fig. a", name.getNomenclaturalMicroReference());
2672

    
2673
        //442A.
2674
        name = parser.parseReferencedName("Rogiera elegans Planch."
2675
                + " in Fl. Serres Jard. Eur. 5: 442A. 1849");
2676
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2677
        combinationAuthor = name.getCombinationAuthorship();
2678
        assertEquals( "Planch.", combinationAuthor.getNomenclaturalTitle());
2679
        nomRef = name.getNomenclaturalReference();
2680
        assertEquals(ReferenceType.Article, nomRef.getType());
2681
        assertEquals("5", nomRef.getVolume());
2682
        assertEquals("442A", name.getNomenclaturalMicroReference());
2683

    
2684
        //f
2685
        name = parser.parseReferencedName("Coussarea imitans L.O. Williams"
2686
                + " in Phytologia 26 (6): 488-489, f. 1973");
2687
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2688
        combinationAuthor = name.getCombinationAuthorship();
2689
        assertEquals( "L.O. Williams", combinationAuthor.getNomenclaturalTitle());
2690
        nomRef = name.getNomenclaturalReference();
2691
        assertEquals(ReferenceType.Article, nomRef.getType());
2692
        assertEquals("26 (6)", nomRef.getVolume());
2693
        assertEquals("488-489, f", name.getNomenclaturalMicroReference());
2694

    
2695
        //Phys.-Med.
2696
        name = parser.parseReferencedName("Coccocypselum cordifolium Nees & Mart."
2697
                + " in Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur. 12: 14. 1824");
2698
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2699
        combinationAuthor = name.getCombinationAuthorship();
2700
        assertEquals( "Nees & Mart.", combinationAuthor.getNomenclaturalTitle());
2701
        nomRef = name.getNomenclaturalReference();
2702
        assertEquals(ReferenceType.Article, nomRef.getType());
2703
        assertEquals("Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur.", nomRef.getInReference().getAbbrevTitle());
2704
        assertEquals("12", nomRef.getVolume());
2705
        assertEquals("14", name.getNomenclaturalMicroReference());
2706
        assertEquals("1824", nomRef.getYear());
2707

    
2708
        //(ed. 10)  wanted?
2709
//        Syst. Nat. (ed. 10) 2: 930. 1759
2710
//        name = parser.parseReferencedName("Erithalis fruticosa L."
2711
//                + ", Syst. Nat. ed. 10, 2: 930. 1759");
2712
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2713
//        combinationAuthor = name.getCombinationAuthorship();
2714
//        assertEquals( "L.", combinationAuthor.getNomenclaturalTitle());
2715
//        nomRef = (Reference)name.getNomenclaturalReference();
2716
//        assertEquals(ReferenceType.Book, nomRef.getType());
2717
//        assertEquals("2", nomRef.getVolume());
2718
//        assertEquals("10", nomRef.getEdition());
2719
//        assertEquals("930", name.getNomenclaturalMicroReference());
2720
//        assertEquals("1759", nomRef.getYear());
2721

    
2722
        //issue with letter "(1a)"
2723
        name = parser.parseReferencedName("Arthraerua (Kuntze) Schinz,"
2724
                + " Nat. Pflanzenfam. 3(1a): 109. 1893");
2725
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2726
        combinationAuthor = name.getCombinationAuthorship();
2727
        assertEquals( "Schinz", combinationAuthor.getNomenclaturalTitle());
2728
        nomRef = name.getNomenclaturalReference();
2729
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
2730
        assertEquals(ReferenceType.Book, nomRef.getType());
2731
        assertEquals("Nat. Pflanzenfam.", nomRef.getAbbrevTitle());
2732
        assertEquals("3(1a)", nomRef.getVolume());
2733
        assertEquals("109", name.getNomenclaturalMicroReference());
2734
        assertEquals("1893", nomRef.getYear());
2735

    
2736
        //Accent graph in author name #6057
2737
        name = parser.parseReferencedName("Sedum plicatum O`Brian");
2738
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2739
        assertEquals( "O`Brian", name.getCombinationAuthorship().getNomenclaturalTitle());
2740

    
2741
        //-e-  #6060
2742
        name = parser.parseReferencedName("Thamniopsis stenodictyon (Sehnem) Oliveira-e-Silva & O.Yano");
2743
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2744
        Team team = (Team)name.getCombinationAuthorship();
2745
        assertEquals( "Oliveira-e-Silva", team.getTeamMembers().get(0).getNomenclaturalTitle());
2746

    
2747
        //Vorabdr.
2748
        name = parser.parseReferencedName("Ophrys hystera  Kreutz & Ruedi Peter in J. Eur. Orchideen 30(Vorabdr.): 128. 1997");
2749
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2750
        assertEquals( "30(Vorabdr.)", name.getNomenclaturalReference().getVolume());
2751

    
2752
        //#6100  jun.
2753
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2754
        name = parser.parseFullName(nameStr, botanicCode, null);  //fails with missing botanicCode, see open issues
2755
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2756
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2757

    
2758
        //#6100 bis /ter
2759
        nameStr = "Schistidium aquaticum (R.Br.ter) Ochyra";
2760
        name = parser.parseFullName(nameStr);
2761
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2762
        assertEquals( "R.Br.ter", name.getBasionymAuthorship().getTitleCache());
2763

    
2764
        nameStr = "Grimmia mitchellii R.Br.bis";
2765
        name = parser.parseFullName(nameStr);
2766
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2767
        assertEquals( "R.Br.bis", name.getCombinationAuthorship().getTitleCache());
2768

    
2769
        //forma #6100
2770
        nameStr = "Xerocomus parasiticus forma piperatoides (J. Blum) R. Mazza";
2771
        name = parser.parseFullName(nameStr);
2772
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2773
        assertEquals( "piperatoides", name.getInfraSpecificEpithet());
2774
        assertEquals( Rank.FORM(), name.getRank());
2775

    
2776
        //subgen. #6100
2777
        nameStr = "Aliciella subgen. Gilmania (H.Mason & A.D.Grant) J.M.Porter";
2778
        name = parser.parseFullName(nameStr);
2779
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2780
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2781
        assertEquals( Rank.SUBGENUS(), name.getRank());
2782

    
2783
        //subgen. #6100
2784
        nameStr = "Aliciella subgen. Gilmania J.M.Porter";
2785
        name = parser.parseFullName(nameStr);
2786
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2787
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2788
        assertEquals( Rank.SUBGENUS(), name.getRank());
2789
        assertEquals( "J.M.Porter", name.getCombinationAuthorship().getTitleCache());
2790

    
2791
        //la Croix #6100
2792
        nameStr = "Eulophia ovalis var. bainesii (Rolfe) P.J.Cribb & la Croix";
2793
        name = parser.parseFullName(nameStr);
2794
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2795
        assertEquals( "P.J.Cribb & la Croix", name.getCombinationAuthorship().getTitleCache());
2796

    
2797
        //I = Yi #6100
2798
        nameStr = "Parasenecio hwangshanicus (P.I Mao) C.I Peng";
2799
        name = parser.parseFullName(nameStr);
2800
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2801
        assertEquals("I (=Yi) should be an accepted ending", "C.I Peng", name.getCombinationAuthorship().getTitleCache());
2802
        assertEquals("I (=Yi) should be an accepted ending", "P.I Mao", name.getBasionymAuthorship().getTitleCache());
2803

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

    
2811
        //Man in 't Veld  #6100
2812
        nameStr = "Phytophthora multivesiculata Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters";
2813
        name = parser.parseFullName(nameStr);
2814
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2815
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
2816
                name.getCombinationAuthorship().getTitleCache());
2817
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
2818
                name.getCombinationAuthorship().getNomenclaturalTitle());
2819

    
2820
        nameStr = "Thymus \u00D7 herberoi De la Torre, Vicedo, Alonso & Paya";
2821
        name = parser.parseFullName(nameStr);
2822
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2823
        //TODO may become ... Alonso & al. again in future
2824
        assertEquals("Thymus \u00D7herberoi De la Torre, Vicedo, Alonso & Paya", name.getTitleCache());
2825
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
2826
                name.getCombinationAuthorship().getTitleCache());
2827
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
2828
                name.getCombinationAuthorship().getNomenclaturalTitle());
2829

    
2830
        //Sant'Anna
2831
        nameStr = "Coelosphaerium evidenter-marginatum M.T.P.Azevedo & Sant'Anna";
2832
        name = parser.parseFullName(nameStr);
2833
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2834
        assertEquals("M.T.P.Azevedo & Sant'Anna", name.getCombinationAuthorship().getTitleCache());
2835

    
2836
        //Heft
2837
        nameStr = "Nepenthes deaniana Macfarl. in Engl., Mein Pflanzenr. IV. 111 (Heft 36): 57. 1908.";
2838
        name = parser.parseReferencedName(nameStr);
2839
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2840
        Reference ref = name.getNomenclaturalReference();
2841
        Assert.assertFalse("Reference should be parsable", ref.hasProblem());
2842
        //or even better IV. 111 (Heft 36), but this is currently not implemented
2843
        assertEquals("111 (Heft 36)", ref.getInReference().getVolume());
2844

    
2845
        //journal with commata at pos 4
2846
        nameStr = "Bufonia kotschyana subsp. densa Chrtek & Krisa in Acta Univ.Carol., Biol. 43(2): 105. 1999";
2847
        name = parser.parseReferencedName(nameStr);
2848
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2849
        String author = name.getAuthorshipCache();
2850
        assertEquals("Chrtek & Krisa", author);
2851
        ref = name.getNomenclaturalReference();
2852
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2853
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2854

    
2855
        //Adansonia #9014, #9551
2856
        nameStr = "Casearia annamensis (Gagnep.) Lescot & Sleumer in Adansonia, n.s., 10: 290. 1970";
2857
        name = parser.parseReferencedName(nameStr);
2858
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2859
        ref = name.getNomenclaturalReference();
2860
        Assert.assertEquals(ReferenceType.Article, ref.getType());
2861
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2862
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2863
        Assert.assertEquals("Adansonia", ref.getInReference().getAbbrevTitle());
2864

    
2865
        //, Bot., sér. 4 #9014, #9551
2866
        String ser = "s"+UTF8.SMALL_E_ACUTE+"r";
2867
        nameStr = "Asteropeia amblyocarpa Tul. in Ann. Sci. Nat., Bot., "+ser+". 4, 8: 81. 1857";
2868
        name = parser.parseReferencedName(nameStr);
2869
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2870
        ref = name.getNomenclaturalReference();
2871
        Assert.assertEquals(ReferenceType.Article, ref.getType());
2872
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2873
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2874
        Assert.assertEquals("Ann. Sci. Nat., Bot.", ref.getInReference().getAbbrevTitle());
2875
        Assert.assertEquals(ser+". 4", ref.getSeriesPart());
2876
    }
2877

    
2878
    @Test
2879
    public final void explicitJournalTitles(){
2880
        //PhytoKeys #9550
2881
        String nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PhytoKeys 137: 68. 2020";
2882
        TaxonName name = parser.parseReferencedName(nameStr);
2883
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2884
        Reference ref = name.getNomenclaturalReference();
2885
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2886
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2887
        Assert.assertEquals("PhytoKeys", ref.getInReference().getAbbrevTitle());
2888

    
2889
        //PLoS ONE #9550 //remaining issue: ", e82692" #9552
2890
//        nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PLoS ONE 8(12), e82692: 17. 2013";
2891
        nameStr = "Pseudopodospermum baeticum (DC.) Zaika & al. in PLoS ONE 8(12): 17. 2013";
2892
        name = parser.parseReferencedName(nameStr);
2893
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2894
        ref = name.getNomenclaturalReference();
2895
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2896
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2897
        Assert.assertEquals("PLoS ONE", ref.getInReference().getAbbrevTitle());
2898
    }
2899

    
2900
    @Test
2901
    //#3666
2902
    public final void testOriginalSpelling(){
2903

    
2904
        String nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa\"]";
2905
        TaxonName name = parser.parseReferencedName(nameStr);
2906
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2907
        Reference ref = name.getNomenclaturalReference();
2908
        Assert.assertFalse("Reference should be parsable", ref.isProtectedTitleCache());
2909
        TaxonName originalName = name.getNomenclaturalSource().getNameUsedInSource();
2910
        Assert.assertNotNull("An original spelling should exist", originalName);
2911
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2912
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
2913
        Assert.assertEquals("Sp. Pl.", name.getNomenclaturalSource().getCitation().getAbbrevTitle());
2914
        Assert.assertEquals("1751", name.getNomenclaturalSource().getCitation().getYear());
2915

    
2916
        //without ref
2917
        nameStr = "Abies alba Mill [as \"alpa\"]";
2918
        name = parser.parseReferencedName(nameStr);
2919
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2920
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2921
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
2922

    
2923
        //without author
2924
        nameStr = "Abies alba [as \"alpa\"]";
2925
        name = parser.parseReferencedName(nameStr);
2926
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2927
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2928
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
2929

    
2930
        //with status
2931
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa\"], nom. inval.";
2932
        name = parser.parseReferencedName(nameStr);
2933
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2934
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2935
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
2936
        Assert.assertEquals(1, name.getStatus().size());
2937

    
2938
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Abies alpa\"]";
2939
        name = parser.parseReferencedName(nameStr);
2940
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2941
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2942
        Assert.assertEquals("Abies alpa", originalName.getNameCache());
2943

    
2944
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Apies alpa\"]";
2945
        name = parser.parseReferencedName(nameStr);
2946
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2947
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2948
        Assert.assertEquals("Apies alpa", originalName.getNameCache());
2949

    
2950
        nameStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"Apies\"]";
2951
        name = parser.parseReferencedName(nameStr);
2952
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2953
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2954
        Assert.assertEquals("Apies alba", originalName.getNameCache());
2955

    
2956
        nameStr = "Abies alba subsp. beta Mill, Sp. Pl. 2: 333. 1751 [as \"peta\"]";
2957
        name = parser.parseReferencedName(nameStr);
2958
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2959
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2960
        Assert.assertEquals("Abies alba subsp. peta", originalName.getNameCache());
2961

    
2962
        nameStr = "Abies alba subsp. beta Mill, Sp. Pl. 2: 333. 1751 [as \"alpa subsp. peta\"]";
2963
        name = parser.parseReferencedName(nameStr);
2964
        originalName = name.getNomenclaturalSource().getNameUsedInSource();
2965
        Assert.assertFalse("Namecache should not be parsable", originalName.isProtectedNameCache());
2966
        Assert.assertEquals("Abies alpa subsp. peta", originalName.getNameCache());
2967

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

    
2972
    }
2973

    
2974
    @Test
2975
    @Ignore
2976
    public final void openIssues(){
2977
        //#6100  jun.
2978
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2979
        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
2980
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2981
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2982
        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
2983
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2984
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2985

    
2986
        //´t Hart #6100
2987
        nameStr = "Sedum decipiens (Baker) Thiede & \u00B4t Hart";   //still does not work with "´" if compiled by maven, don't know what the difference is
2988
        name = parser.parseFullName(nameStr);
2989
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2990
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2991
                "Thiede & \u00B4t Hart", name.getCombinationAuthorship().getTitleCache());
2992
        nameStr = "Sedum decipiens (Baker) Thiede & ´t Hart";   //does not work if compiled with maven
2993
        name = parser.parseFullName(nameStr);
2994
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2995
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2996
                "Thiede & ´t Hart", name.getCombinationAuthorship().getTitleCache());
2997

    
2998
        //should be recognized as book section (see testBookSectionAuthors)
2999
        String str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
3000
        name = parser.parseReferencedName(str);
3001
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3002
        Reference nomRef = name.getNomenclaturalReference();
3003
        assertEquals(ReferenceType.BookSection, nomRef.getType());
3004
        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
3005
        assertEquals( "Nova Fl. Portugal", nomRef.getInReference().getAbbrevTitle());
3006

    
3007
        //same
3008
        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
3009
        name = parser.parseReferencedName(str);
3010
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
3011
        nomRef = name.getNomenclaturalReference();
3012
        assertEquals(ReferenceType.BookSection, nomRef.getType());
3013
        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
3014
        assertEquals( "Mount. Fl. Greece", nomRef.getInReference().getAbbrevTitle());
3015
    }
3016

    
3017
}
(2-2/4)