Project

General

Profile

Download (173 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

    
10
package eu.etaxonomy.cdm.strategy.parser;
11

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

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

    
24
import org.apache.log4j.Logger;
25
import org.joda.time.DateTime;
26
import org.joda.time.Duration;
27
import org.junit.Assert;
28
import org.junit.Before;
29
import org.junit.BeforeClass;
30
import org.junit.Ignore;
31
import org.junit.Test;
32

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

    
60
/**
61
 * Tests for {@link NonViralNameParserImpl}.
62
 *
63
 * @author a.mueller
64
 */
65
public class NonViralNameParserImplTest {
66

    
67
    private static final NomenclaturalCode ICNAFP = NomenclaturalCode.ICNAFP;
68
    private static final NomenclaturalCode ICZN = NomenclaturalCode.ICZN;
69

    
70
    private static final String SEP = TimePeriod.SEP;
71

    
72
    private static final Logger logger = Logger.getLogger(NonViralNameParserImplTest.class);
73

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

    
89
    final private String strNameEmpty = "";
90
    final private String strNameNull = null;
91

    
92
    private NonViralNameParserImpl parser ;
93
    private NomenclaturalCode botanicCode;
94

    
95
    @BeforeClass
96
    public static void setUpBeforeClass() throws Exception {
97
        DefaultTermInitializer termInitializer = new DefaultTermInitializer();
98
        termInitializer.initialize();
99
    }
100

    
101
    @Before
102
    public void setUp() throws Exception {
103
        parser = NonViralNameParserImpl.NewInstance();
104
        botanicCode = ICNAFP;
105
    }
106

    
107
/*************** TEST *********************************************/
108

    
109
    /**
110
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#NEW_INSTANCE()}.
111
     */
112
    @Test
113
    public final void testNewInstance() {
114
        assertNotNull(parser);
115
    }
116

    
117
    /**
118
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#TaxonNameParserBotanicalNameImpl()}.
119
     */
120
    @Test
121
    public final void testTaxonNameParserBotanicalNameImpl() {
122
        logger.warn("Not yet implemented"); // TODO
123
    }
124

    
125
    @Test
126
    public final void testTeamSeperation(){
127
        Rank speciesRank = Rank.SPECIES();
128
        INonViralName name;
129

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

    
144
        String strNameWith3Authors = "Abies alba Mess., L. & Mill., Sp. Pl., ed. 3: 455. 1987";
145
        name = parser.parseReferencedName(strNameWith3Authors, botanicCode, speciesRank);
146
        Assert.assertFalse("No problems should exist", name.hasProblem());
147
        Assert.assertEquals("Name should not include reference part", "Abies alba Mess., L. & Mill.", name.getTitleCache());
148
        Assert.assertEquals("Name should have authorship with 2 authors", 3, ((Team)name.getCombinationAuthorship()).getTeamMembers().size());
149
        Assert.assertEquals("Mess., L. & Mill., Sp. Pl., ed. 3. 1987", name.getNomenclaturalReference().getTitleCache());
150

    
151
    }
152

    
153
    /**
154
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseSimpleName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
155
     */
156
    @Test
157
    public final void testParseSimpleName() {
158

    
159
        //Uninomials
160
        IZoologicalName milichiidae = (IZoologicalName)parser.parseSimpleName("Milichiidae", NomenclaturalCode.ICZN, null);
161
        assertEquals("Family rank expected", Rank.FAMILY(), milichiidae.getRank());
162
        IBotanicalName crepidinae = (IBotanicalName)parser.parseSimpleName("Crepidinae", ICNAFP, null);
163
        assertEquals("Family rank expected", Rank.SUBTRIBE(), crepidinae.getRank());
164
        IBotanicalName abies = (IBotanicalName)parser.parseSimpleName("Abies", ICNAFP, null);
165
        assertEquals("Family rank expected", Rank.GENUS(), abies.getRank());
166

    
167
        abies.addParsingProblem(ParserProblem.CheckRank);
168
        parser.parseSimpleName(abies, "Abies", abies.getRank(), true);
169
        assertTrue(abies.getParsingProblems().contains(ParserProblem.CheckRank));
170

    
171
        IBotanicalName rosa = (IBotanicalName)parser.parseSimpleName("Rosaceae", ICNAFP, null);
172
        assertTrue("Rosaceae have rank family", rosa.getRank().equals(Rank.FAMILY()));
173
        assertTrue("Rosaceae must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
174
        parser.parseSimpleName(rosa, "Rosaceaex", abies.getRank(), true);
175
        assertEquals("Rosaceaex have rank genus", Rank.GENUS(), rosa.getRank());
176
        assertTrue("Rosaceaex must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
177

    
178
        //repeat but remove warning after first parse
179
        rosa = (IBotanicalName)parser.parseSimpleName("Rosaceae", ICNAFP, null);
180
        assertTrue("Rosaceae have rank family", rosa.getRank().equals(Rank.FAMILY()));
181
        assertTrue("Rosaceae must have a rank warning", rosa.hasProblem(ParserProblem.CheckRank));
182
        rosa.removeParsingProblem(ParserProblem.CheckRank);
183
        parser.parseSimpleName(rosa, "Rosaceaex", rosa.getRank(), true);
184
        assertEquals("Rosaceaex have rank family", Rank.FAMILY(), rosa.getRank());
185
        assertFalse("Rosaceaex must have no rank warning", rosa.hasProblem(ParserProblem.CheckRank));
186

    
187
    }
188

    
189
    /**
190
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseSubGenericFullName(java.lang.String)}.
191
     */
192
    @Test
193
    public final void testParseSubGenericFullName() {
194
        String zooSpeciesWithSubgenus = "Bacanius (Mullerister) rombophorus (Aube, 1843)";
195
        //zoo as fullName
196
        IZoologicalName zooName = parser.parseReferencedName(zooSpeciesWithSubgenus, NomenclaturalCode.ICZN, Rank.SPECIES());
197
        Assert.assertTrue(zooName.getParsingProblems().isEmpty());
198
        Assert.assertEquals("Mullerister", zooName.getInfraGenericEpithet());
199
        Assert.assertEquals(Integer.valueOf(1843), zooName.getOriginalPublicationYear());
200
        //zoo as referenced name
201
        zooName = (IZoologicalName)parser.parseFullName(zooSpeciesWithSubgenus, NomenclaturalCode.ICZN, Rank.SPECIES());
202
        Assert.assertTrue(zooName.getParsingProblems().isEmpty());
203
        Assert.assertEquals("Mullerister", zooName.getInfraGenericEpithet());
204
        Assert.assertEquals(Integer.valueOf(1843), zooName.getOriginalPublicationYear());
205

    
206
        //bot as full Name
207
        String botSpeciesWithSubgenus = "Bacanius (Mullerister) rombophorus (Aube) Mill.";
208
        IBotanicalName botName = (IBotanicalName)parser.parseFullName(botSpeciesWithSubgenus, NomenclaturalCode.ICNAFP, Rank.GENUS());
209
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
210
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
211
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
212
        Assert.assertEquals("Aube", botName.getBasionymAuthorship().getTitleCache());
213

    
214
        //bot as referenced Name
215
        botName = parser.parseReferencedName(botSpeciesWithSubgenus, NomenclaturalCode.ICNAFP, Rank.GENUS());
216
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
217
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
218
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
219
        Assert.assertEquals("Aube", botName.getBasionymAuthorship().getTitleCache());
220

    
221
        //bot without author
222
        String botSpeciesWithSubgenusWithoutAuthor = "Bacanius (Mullerister) rombophorus";
223
        botName = parser.parseReferencedName(botSpeciesWithSubgenusWithoutAuthor, NomenclaturalCode.ICNAFP, Rank.GENUS());
224
        Assert.assertTrue(botName.getParsingProblems().isEmpty());
225
        Assert.assertEquals("Mullerister", botName.getInfraGenericEpithet());
226
        Assert.assertEquals("rombophorus", botName.getSpecificEpithet());
227
        Assert.assertEquals("", botName.getAuthorshipCache());
228
    }
229

    
230
    /**
231
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseSubGenericSimpleName(java.lang.String)}.
232
     */
233
    @Test
234
    public final void testParseSubGenericSimpleName() {
235
        logger.warn("Not yet implemented"); // TODO
236
    }
237

    
238
    /**
239
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
240
     */
241
    @Test
242
    public final void testParseFullNameUnicode() {
243

    
244
        INonViralName nameAuthor = parser.parseFullName(strNameAbiesAuthor1Unicode, null, Rank.SPECIES());
245
        assertEquals("Abies", nameAuthor.getGenusOrUninomial());
246
        assertEquals("alba", nameAuthor.getSpecificEpithet());
247
        assertEquals("M\u00FCller", nameAuthor.getCombinationAuthorship().getNomenclaturalTitle());
248

    
249
        INonViralName nameBasionymAuthor = parser.parseFullName(strNameAbiesBasionymAuthor1Unicode, null, Rank.SPECIES());
250
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
251
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
252
        assertEquals("D'M\u00FCller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitle());
253
        INomenclaturalAuthor basionymTeam = nameBasionymAuthor.getBasionymAuthorship();
254
        assertEquals("Ciardelli", basionymTeam.getNomenclaturalTitle());
255

    
256
        INonViralName nameBasionymExAuthor = parser.parseFullName(strNameAbiesBasionymExAuthor1Unicode, null, Rank.SPECIES());
257
        assertEquals("Abies", nameBasionymExAuthor.getGenusOrUninomial());
258
        assertEquals("alba", nameBasionymExAuthor.getSpecificEpithet());
259
        assertEquals("D'M\u00FCller", nameBasionymExAuthor.getExCombinationAuthorship().getNomenclaturalTitle());
260
        assertEquals("de Greuther", nameBasionymExAuthor.getCombinationAuthorship().getNomenclaturalTitle());
261
        INomenclaturalAuthor basionymTeam2 = nameBasionymExAuthor.getExBasionymAuthorship();
262
        assertEquals("Ciardelli", basionymTeam2.getNomenclaturalTitle());
263
        INomenclaturalAuthor exBasionymTeam2 = nameBasionymExAuthor.getBasionymAuthorship();
264
        assertEquals("D\u00F6ring", exBasionymTeam2.getNomenclaturalTitle());
265

    
266
        IBotanicalName nameBasionymExAuthor2 = (IBotanicalName)parser.parseFullName("Washingtonia filifera (Linden ex Andre) H.Wendl. ex de Bary", null, Rank.SPECIES());
267
        assertEquals("Washingtonia", nameBasionymExAuthor2.getGenusOrUninomial());
268
        assertEquals("filifera", nameBasionymExAuthor2.getSpecificEpithet());
269
        assertEquals("H.Wendl.", nameBasionymExAuthor2.getExCombinationAuthorship().getNomenclaturalTitle());
270
        assertEquals("de Bary", nameBasionymExAuthor2.getCombinationAuthorship().getNomenclaturalTitle());
271
        INomenclaturalAuthor basionymTeam3 = nameBasionymExAuthor2.getBasionymAuthorship();
272
        assertEquals("Andre", basionymTeam3.getNomenclaturalTitle());
273
        INomenclaturalAuthor exBasionymTeam3 = nameBasionymExAuthor2.getExBasionymAuthorship();
274
        assertEquals("Linden", exBasionymTeam3.getNomenclaturalTitle());
275
        String title = nameBasionymExAuthor2.getTitleCache();
276
        assertEquals("Washingtonia filifera (Linden ex Andre) H.Wendl. ex de Bary", title);
277

    
278
    }
279

    
280

    
281
    /**
282
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
283
     */
284
    @Test
285
    public final void testParseFullName() {
286
        try {
287
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
288
            testName_StringNomcodeRank(parseMethod);
289
        } catch (Exception e) {
290
            e.printStackTrace();
291
            assertTrue(false);
292
        }
293

    
294
        //Team
295
        INonViralName nameTeam1 = parser.parseFullName(strNameTeam1);
296
        assertEquals( "Abies", nameTeam1.getGenusOrUninomial());
297
        assertEquals( "alba", nameTeam1.getSpecificEpithet());
298
        assertEquals("Mueller & L.",  nameTeam1.getCombinationAuthorship().getNomenclaturalTitle());
299
        assertTrue(nameTeam1.getCombinationAuthorship() instanceof Team);
300
        Team team = (Team)nameTeam1.getCombinationAuthorship();
301
        assertEquals("Mueller", team.getTeamMembers().get(0).getNomenclaturalTitle());
302
        assertEquals("L.", team.getTeamMembers().get(1).getNomenclaturalTitle());
303

    
304
        //ZooName
305
        IZoologicalName nameZoo1 = (IZoologicalName)parser.parseFullName(strNameZoo1);
306
        assertEquals( "Abies", nameZoo1.getGenusOrUninomial());
307
        assertEquals( "alba", nameZoo1.getSpecificEpithet());
308
        assertEquals("Mueller & L.",  nameZoo1.getCombinationAuthorship().getNomenclaturalTitle());
309
        assertEquals(NomenclaturalCode.ICZN, nameZoo1.getNameType() );
310
        assertEquals(Integer.valueOf(1822), nameZoo1.getPublicationYear());
311
        assertTrue(nameZoo1.getCombinationAuthorship() instanceof Team);
312
        Team teamZoo = (Team)nameZoo1.getCombinationAuthorship();
313
        assertEquals("Mueller", teamZoo.getTeamMembers().get(0).getNomenclaturalTitle());
314
        assertEquals("L.", teamZoo.getTeamMembers().get(1).getNomenclaturalTitle());
315

    
316
        IZoologicalName nameZoo2 = (IZoologicalName)parser.parseFullName(strNameZoo2);
317
        assertEquals(Integer.valueOf(2002), nameZoo2.getPublicationYear());
318
        assertEquals(Integer.valueOf(1822), nameZoo2.getOriginalPublicationYear());
319
        assertEquals("Mueller",  nameZoo2.getBasionymAuthorship().getNomenclaturalTitle());
320
        assertEquals("Ciardelli",  nameZoo2.getCombinationAuthorship().getNomenclaturalTitle());
321

    
322
        //subsp
323
        IZoologicalName nameZoo3 = (IZoologicalName)parser.parseFullName(strNameZoo3);
324
        assertEquals("Ciardelli",  nameZoo3.getCombinationAuthorship().getNomenclaturalTitle());
325
        assertFalse("Subsp. without marker should be parsable", nameZoo3.hasProblem());
326
        assertEquals("Variety should be recognized", Rank.SUBSPECIES(), nameZoo3.getRank());
327

    
328
        IZoologicalName nameZoo4 = (IZoologicalName)parser.parseFullName(strNameZoo4);
329
        assertEquals("Ciardelli",  nameZoo4.getCombinationAuthorship().getNomenclaturalTitle());
330
        assertFalse("Subsp. without marker should be parsable", nameZoo4.hasProblem());
331
        assertEquals("Variety should be recognized", Rank.SUBSPECIES(), nameZoo4.getRank());
332

    
333
        IZoologicalName nameZoo5 = (IZoologicalName)parser.parseFullName(strNameZoo5);
334
        assertEquals("Ciardelli",  nameZoo5.getCombinationAuthorship().getNomenclaturalTitle());
335
        assertFalse("Subsp. without marker should be parsable", nameZoo5.hasProblem());
336
        assertEquals("Variety should be recognized", Rank.VARIETY(), nameZoo5.getRank());
337

    
338
        //empty
339
        INonViralName nameEmpty = parser.parseFullName(strNameEmpty);
340
        assertNotNull(nameEmpty);
341
        assertEquals("", nameEmpty.getTitleCache());
342

    
343
        //null
344
        INonViralName nameNull = parser.parseFullName(strNameNull);
345
        assertNull(nameNull);
346

    
347
        //some authors
348
        String fullNameString = "Abies alba (Greuther & L'Hiver & al. ex M\u00FCller & Schmidt)Clark ex Ciardelli";
349
        INonViralName authorname = parser.parseFullName(fullNameString);
350
        assertFalse(authorname.hasProblem());
351
        assertEquals("Basionym author should have 3 authors", 2, ((Team)authorname.getExBasionymAuthorship()).getTeamMembers().size());
352
        Assert.assertTrue("ExbasionymAuthorship must have more members'", ((Team)authorname.getExBasionymAuthorship()).isHasMoreMembers());
353

    
354
        //author with 2 capitals
355
        fullNameString = "Campanula rhodensis A. DC.";
356
        INonViralName name = parser.parseFullName(fullNameString);
357
        assertFalse(name.hasProblem());
358

    
359
        //author with no space  #5618
360
        fullNameString = "Gordonia moaensis (Vict.)H. Keng";
361
        name = parser.parseFullName(fullNameString);
362
        assertFalse(name.hasProblem());
363
        assertNotNull(name.getCombinationAuthorship());
364
        assertEquals("H. Keng", name.getCombinationAuthorship().getNomenclaturalTitle());
365

    
366
        //name without combination  author  , only to check if above fix for #5618 works correctly
367
        fullNameString = "Gordonia moaensis (Vict.)";
368
        name = parser.parseFullName(fullNameString);
369
        assertFalse(name.hasProblem());
370
        assertNull(name.getCombinationAuthorship());
371
        assertNotNull(name.getBasionymAuthorship());
372
        assertEquals("Vict.", name.getBasionymAuthorship().getNomenclaturalTitle());
373

    
374
    }
375

    
376
    @Test
377
    public final void testAutonyms(){
378
        TaxonName autonymName;
379
        //infraspecific
380
        autonymName = (TaxonName)parser.parseFullName("Abies alba Mill. var. alba", ICNAFP, null);
381
        assertFalse("Autonym should be parsable", autonymName.hasProblem());
382
        autonymName = parser.parseReferencedName("Abies alba Mill. var. alba", ICNAFP, null);
383
        assertFalse("Autonym should be parsable", autonymName.hasProblem());
384
        //infrageneric
385
        autonymName = (TaxonName)parser.parseFullName("Abies Mill. sect. Abies", ICNAFP, null);
386
        assertFalse("Genus autonym should be parsable", autonymName.hasProblem());
387
        assertEquals("Rank should be section (bot.)", Rank.SECTION_BOTANY(), autonymName.getRank());
388
        autonymName = parser.parseReferencedName("Achnanthes Bory sect. Achnanthes", ICNAFP, null);
389
        assertFalse("Genus autonym should be parsable", autonymName.hasProblem());
390
        assertEquals("Rank should be section (bot.)", Rank.SECTION_BOTANY(), autonymName.getRank());
391
    }
392

    
393
    @Test
394
    public final void testEtAl() throws StringNotParsableException {
395
        //some authors
396
        String fullNameString = "Abies alba Greuther, Hiver & al.";
397
        INonViralName authorname = parser.parseFullName(fullNameString);
398
        assertFalse(authorname.hasProblem());
399
        assertEquals("Basionym author should have 2 authors", 2, ((Team)authorname.getCombinationAuthorship()).getTeamMembers().size());
400
        assertTrue("Basionym author team should have more authors", ((Team)authorname.getCombinationAuthorship()).isHasMoreMembers()  );
401

    
402
        //et al.
403
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
404
        parser.parseAuthors(nvn, "Eckweiler, Hand et al., 2003");
405
        Team team = (Team)nvn.getCombinationAuthorship();
406
        Assert.assertNotNull("Comb. author must not be null", team);
407
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
408
        Assert.assertEquals("Second member must be 'Hand'", "Hand", team.getTeamMembers().get(1).getTitleCache());
409
        Assert.assertTrue("Team must have more members'", team.isHasMoreMembers());
410
    }
411

    
412
    @Test
413
    public final void testMultipleAuthors() {
414
        //multiple authors for inReference
415
        String fullTitleString = "Abies alba L. in Mill., Gregor & Behr., Sp. Pl. 173: 384. 1982.";
416
        INonViralName multipleAuthorRefName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
417
        assertFalse(multipleAuthorRefName.hasProblem());
418
        assertTrue("Combination author should be a person", multipleAuthorRefName.getCombinationAuthorship() instanceof Person);
419
        assertEquals("Combination author should be L.", "L.", ((Person)multipleAuthorRefName.getCombinationAuthorship()).getNomenclaturalTitle());
420
        Reference nomRef = multipleAuthorRefName.getNomenclaturalReference();
421
        Assert.assertNotNull("nomRef must have inRef", nomRef.getInReference());
422
        Reference inRef = nomRef.getInReference();
423
        String abbrevTitle = inRef.getAbbrevTitle();
424
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
425
        assertTrue(inRef.getAuthorship() instanceof Team);
426
        Team team = (Team)inRef.getAuthorship();
427
        assertEquals(3, team.getTeamMembers().size());
428

    
429
//        multiple authors in Name
430
        fullTitleString = "Abies alba Mill., Aber & Schwedt";
431
        INonViralName multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
432
        assertFalse(multipleAuthorName.hasProblem());
433
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
434
        team = (Team)multipleAuthorName.getCombinationAuthorship();
435
        assertEquals(3, team.getTeamMembers().size());
436
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
437

    
438
//      multiple authors in Name with reference
439
        fullTitleString = "Abies alba Mill., Aber & Schwedt in L., Sp. Pl. 173: 384. 1982.";
440
        multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
441
        assertFalse(multipleAuthorName.hasProblem());
442
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
443
        team = (Team)multipleAuthorName.getCombinationAuthorship();
444
        assertEquals(3, team.getTeamMembers().size());
445
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
446
        nomRef = multipleAuthorName.getNomenclaturalReference();
447
        Assert.assertNotNull("nomRef must have inRef", nomRef.getInReference());
448
        inRef = nomRef.getInReference();
449
        abbrevTitle = inRef.getAbbrevTitle();
450
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
451
        assertTrue(inRef.getAuthorship() instanceof Person);
452
        Person person = (Person)inRef.getAuthorship();
453
        assertEquals("Book author should be L.", "L.", person.getNomenclaturalTitle());
454

    
455

    
456
        fullTitleString = "Abies alba Mill., Aber & Schwedt, Sp. Pl. 173: 384. 1982.";
457
        multipleAuthorName = parser.parseReferencedName(fullTitleString, NomenclaturalCode.ICNAFP, Rank.SPECIES());
458
        assertFalse(multipleAuthorName.hasProblem());
459
        assertTrue("Combination author should be a team", multipleAuthorName.getCombinationAuthorship() instanceof Team);
460
        team = (Team)multipleAuthorName.getCombinationAuthorship();
461
        assertEquals(3, team.getTeamMembers().size());
462
        assertEquals("Second team member should be Aber", "Aber", team.getTeamMembers().get(1).getTitleCache());
463
        nomRef = multipleAuthorName.getNomenclaturalReference();
464
        Assert.assertNull("nomRef must not have inRef as it is a book itself", nomRef.getInReference());
465
        abbrevTitle = nomRef.getAbbrevTitle();
466
        assertEquals("InRef title should be Sp. Pl.", "Sp. Pl.", abbrevTitle);
467
        assertTrue(nomRef.getAuthorship() instanceof Team);
468
        team = (Team)nomRef.getAuthorship();
469
        assertEquals(3, team.getTeamMembers().size());
470
        assertEquals("Second team member should be Schwedt", "Schwedt", team.getTeamMembers().get(2).getTitleCache());
471

    
472
        //et al.
473
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
474
        parser.parseReferencedName (nvn, "Marmota marmota Eckweiler, Hand et al., 2003", Rank.SPECIES(),true);
475
        assertTrue("Combination author should be a team", nvn.getCombinationAuthorship() instanceof Team);
476
        team = (Team)nvn.getCombinationAuthorship();
477
        Assert.assertNotNull("Comb. author must not be null", team);
478
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
479
        Assert.assertEquals("Second member must be 'Hand'", "Hand", team.getTeamMembers().get(1).getTitleCache());
480
        Assert.assertTrue("Team must have more members'", team.isHasMoreMembers());
481

    
482
    }
483

    
484
    @Test
485
    public final void testHybrids() {
486
        INonViralName name1;
487

    
488
        //Infrageneric hybrid
489
        name1 = parser.parseFullName("Aegilops nothosubg. Insulae Scholz", botanicCode, null);
490
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
491
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
492
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
493
        assertEquals("Infrageneric epithet must be 'Insulae'", "Insulae", name1.getInfraGenericEpithet());
494

    
495
        //Species hybrid
496
//      INonViralName nameTeam1 = parser.parseFullName("Aegilops \u00D7insulae-cypri H. Scholz");
497
        name1 = parser.parseFullName("Aegilops \u00D7insulae Scholz", botanicCode, null);
498
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
499
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
500
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
501
        assertEquals("Species epithet must be 'insulae'", "insulae", name1.getSpecificEpithet());
502

    
503
        name1 = parser.parseFullName("Aegilops \u00D7 insulae Scholz", botanicCode, null);
504
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
505
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
506
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
507
        assertEquals("Species epithet must be 'insulae'", "insulae", name1.getSpecificEpithet());
508

    
509
        //Uninomial hybrid
510
        name1 = parser.parseFullName("x Aegilops Scholz", botanicCode, null);
511
        assertTrue("Name must have monom hybrid bit set", name1.isMonomHybrid());
512
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
513
        assertFalse("Name must not have trinom hybrid bit set", name1.isTrinomHybrid());
514
        assertEquals("Uninomial must be 'Aegilops'", "Aegilops", name1.getGenusOrUninomial());
515

    
516
        //Subspecies hybrid with hybrid sign
517
        //maybe false: see http://dev.e-taxonomy.eu/trac/ticket/3868
518
        name1 = parser.parseFullName("Aegilops insulae subsp. X abies Scholz", botanicCode, null);
519
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
520
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
521
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
522
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
523

    
524
        //Subspecies hybrid with notho / n
525
        name1 = parser.parseFullName("Aegilops insulae nothosubsp. abies Scholz", botanicCode, null);
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
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
529
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
530
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
531

    
532
        name1 = parser.parseFullName("Aegilops insulae nsubsp. abies Scholz", botanicCode, null);
533
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
534
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
535
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
536
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
537
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
538

    
539
        //
540
        String nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
541
        name1 = parser.parseFullName(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
        nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
549
        name1 = parser.parseFullName(nameStr);
550
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
551
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
552
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
553
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
554
        assertEquals(nameStr, name1.getTitleCache());  //we expect the cache strategy to create the same result
555

    
556
        //nothovar.
557
        nameStr = "Dactylorhiza incarnata nothovar. versicolor";
558
        name1 = parser.parseFullName(nameStr);
559
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
560
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
561
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
562
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
563
        assertEquals(nameStr, name1.getNameCache());  //we expect the cache strategy to create the same result
564

    
565
        //hybrid autonym #6656
566
        nameStr = "Ophrys \u00D7kastelli E. Klein nothosubsp. kastelli";
567
        name1 = parser.parseFullName(nameStr);
568
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
569
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
570
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
571
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
572
        assertEquals(nameStr, name1.getTitleCache()); //we expect the cache strategy to create the same result
573

    
574
        name1 = parser.parseReferencedName(nameStr);
575
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
576
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
577
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
578
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
579
        assertEquals(nameStr, name1.getTitleCache()); //we expect the cache strategy to create the same result
580

    
581
        //remove space since #7094
582
        parser.setRemoveSpaceAfterDot(true);
583
        name1 = parser.parseReferencedName(nameStr);
584
        assertEquals(nameStr.replace("E. Kl", "E.Kl"), name1.getTitleCache()); //we expect the cache strategy to create the same result
585
        parser.setRemoveSpaceAfterDot(false);
586

    
587

    
588

    
589
    }
590

    
591
    @Test
592
    public final void testHybridFormulars() {
593
        try {
594
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
595
            testName_StringNomcodeRank(parseMethod);
596
        } catch (Exception e) {
597
            e.printStackTrace();
598
            assertTrue(false);
599
        }
600

    
601
        //Species hybrid
602
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
603
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
604
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
605
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
606
        assertEquals("Title cache must be correct", hybridCache, name1.getTitleCache());
607
        List<HybridRelationship> orderedRels = name1.getOrderedChildRelationships();
608
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
609
        TaxonName firstParent = orderedRels.get(0).getParentName();
610
        assertEquals("Name must have Abies alba as first hybrid parent", "Abies alba", firstParent.getTitleCache());
611
        TaxonName secondParent = orderedRels.get(1).getParentName();
612
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
613
        assertEquals("Hybrid name must have the lowest rank ('species') as rank", Rank.SPECIES(), name1.getRank());
614
        assertNull("Name must not have a genus eptithet", name1.getGenusOrUninomial());
615
        assertNull("Name must not have a specific eptithet", name1.getSpecificEpithet());
616
        assertFalse("Name must not have parsing problems", name1.hasProblem());
617

    
618
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
619
        assertFalse("Name must not have parsing problems", name1.hasProblem());
620

    
621
        //x-sign
622
        hybridCache = "Abies alba x Pinus bus";
623
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
624
        assertFalse("Name must be parsable", name1.hasProblem());
625
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
626
        assertFalse("Name must not have parsing problems", name1.hasProblem());
627

    
628
        //Genus //#6030
629
        hybridCache = "Orchis "+UTF8.HYBRID+" Platanthera";
630
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
631
        assertFalse("Name must be parsable", name1.hasProblem());
632
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
633
        assertFalse("Name must not have parsing problems", name1.hasProblem());
634
        assertEquals("Title cache must be correct", hybridCache, 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 Orchis as first hybrid parent", "Orchis", firstParent.getTitleCache());
639
        secondParent = orderedRels.get(1).getParentName();
640
        assertEquals("Name must have Platanthera as second hybrid parent", "Platanthera", secondParent.getTitleCache());
641
        assertEquals("Hybrid name must have genus as rank", Rank.GENUS(), name1.getRank());
642

    
643
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
644
        assertFalse("Name must not have parsing problems", name1.hasProblem());
645

    
646
        //Subspecies first hybrid
647
        name1 = parser.parseFullName("Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", botanicCode, null);
648
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
649
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
650
        assertEquals("Title cache must be correct", "Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", name1.getTitleCache());
651
        orderedRels = name1.getOrderedChildRelationships();
652
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
653
        firstParent = orderedRels.get(0).getParentName();
654
        assertEquals("Name must have Abies alba subsp. beta as first hybrid parent", "Abies alba subsp. beta", firstParent.getTitleCache());
655
        secondParent = orderedRels.get(1).getParentName();
656
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
657
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
658

    
659
        //variety second hybrid
660
        name1 = parser.parseFullName("Abies alba \u00D7 Pinus bus  var. beta", botanicCode, null);
661
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
662
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
663
        assertEquals("Title cache must be correct", "Abies alba \u00D7 Pinus bus var. beta", name1.getTitleCache());
664
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
665

    
666
        //hybrids with authors  //happens but questionable
667
        name1 = parser.parseFullName("Abies alba L. \u00D7 Pinus bus Mill.", botanicCode, null);
668
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
669
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
670
        assertEquals("Title cache must be correct", "Abies alba L. \u00D7 Pinus bus Mill.", name1.getTitleCache());
671
        orderedRels = name1.getOrderedChildRelationships();
672
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
673
        firstParent = orderedRels.get(0).getParentName();
674
        assertEquals("Name must have Abies alba L. as first hybrid parent", "Abies alba L.", firstParent.getTitleCache());
675
        secondParent = orderedRels.get(1).getParentName();
676
        assertEquals("Name must have Pinus bus Mill. as second hybrid parent", "Pinus bus Mill.", secondParent.getTitleCache());
677
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
678

    
679
        //abbreviated genus hybrid formula #6410 / #5983
680
        String nameStr = "Nepenthes mirabilis \u00D7 N. alata";
681
        name1 = parser.parseFullName(nameStr, botanicCode, null);
682
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
683
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
684
        //could also be N. or no genus at all, depends on formatter
685
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
686
        orderedRels = name1.getOrderedChildRelationships();
687
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
688
        firstParent = orderedRels.get(0).getParentName();
689
        //to be discussed as usually they should be ordered alphabetically
690
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
691
        secondParent = orderedRels.get(1).getParentName();
692
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
693
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
694

    
695
        //missing genus hybrid formula #5983
696
        nameStr = "Nepenthes mirabilis \u00D7 alata";
697
        name1 = parser.parseFullName(nameStr, botanicCode, null);
698
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
699
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
700
        //could also be N. or no genus at all, depends on formatter
701
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
702
        orderedRels = name1.getOrderedChildRelationships();
703
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
704
        firstParent = orderedRels.get(0).getParentName();
705
        //to be discussed as usually they should be ordered alphabetically
706
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
707
        secondParent = orderedRels.get(1).getParentName();
708
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
709
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
710

    
711
        //#5983 subsp. with species and missing genus
712
        nameStr = "Orchis coriophora subsp. fragrans \u00D7 sancta";
713
        name1 = parser.parseFullName(nameStr, botanicCode, null);
714
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
715
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
716
        //could also be N. or no genus at all, depends on formatter
717
        assertEquals("Title cache must be correct", "Orchis coriophora subsp. fragrans \u00D7 Orchis sancta", name1.getTitleCache());
718
        orderedRels = name1.getOrderedChildRelationships();
719
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
720
        firstParent = orderedRels.get(0).getParentName();
721
        assertEquals("Name must have Orchis coriophora subsp. fragrans as first hybrid parent", "Orchis coriophora subsp. fragrans", firstParent.getTitleCache());
722
        secondParent = orderedRels.get(1).getParentName();
723
        assertEquals("Name must have Orchis sancta as second hybrid parent", "Orchis sancta", secondParent.getTitleCache());
724
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
725

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

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

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

    
771
        //2 subspecies with missing genus and species part #5983
772
        nameStr = "Orchis morio subsp. syriaca \u00D7 subsp. schirvanica";
773
        name1 = parser.parseFullName(nameStr, botanicCode, null);
774
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
775
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
776
        //could also be N. or no genus at all, depends on formatter
777
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio subsp. schirvanica", name1.getTitleCache());
778
        orderedRels = name1.getOrderedChildRelationships();
779
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
780
        firstParent = orderedRels.get(0).getParentName();
781
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
782
        secondParent = orderedRels.get(1).getParentName();
783
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio subsp. schirvanica", secondParent.getTitleCache());
784
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
785

    
786
        //subspecies and variety with missing genus and species part #5983
787
        nameStr = "Orchis morio subsp. syriaca \u00D7 var. schirvanica";
788
        name1 = parser.parseFullName(nameStr, botanicCode, null);
789
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
790
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
791
        //could also be N. or no genus at all, depends on formatter
792
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio var. schirvanica", name1.getTitleCache());
793
        orderedRels = name1.getOrderedChildRelationships();
794
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
795
        firstParent = orderedRels.get(0).getParentName();
796
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
797
        secondParent = orderedRels.get(1).getParentName();
798
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio var. schirvanica", secondParent.getTitleCache());
799
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
800
    }
801

    
802

    
803
    @Test
804
    public final void testUnrankedNames() {
805
        try {
806
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
807
            testName_StringNomcodeRank(parseMethod);
808
        } catch (Exception e) {
809
            e.printStackTrace();
810
            assertTrue(false);
811
        }
812

    
813
        //unranked infraspecific
814
        String infraspecificUnranked = "Genus species [unranked] infraspecific";
815
        INonViralName name = parser.parseFullName(infraspecificUnranked);
816
        assertEquals( "Genus", name.getGenusOrUninomial());
817
        assertEquals( "species", name.getSpecificEpithet());
818
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
819
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
820

    
821
        //'ranglos' infraspecific
822
        infraspecificUnranked = "Genus species [ranglos] infraspecific";
823
        name = parser.parseFullName(infraspecificUnranked);
824
        assertEquals( "Genus", name.getGenusOrUninomial());
825
        assertEquals( "species", name.getSpecificEpithet());
826
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
827
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
828

    
829
        //unranked infrageneric
830
        String infraGenericUnranked = "Genus [unranked] Infragen";
831
        INonViralName name2 = parser.parseFullName(infraGenericUnranked);
832
        assertEquals( "Genus", name2.getGenusOrUninomial());
833
        assertEquals( null, name2.getSpecificEpithet());
834
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
835
        assertEquals( "Unranked rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
836

    
837
        //unranked infrageneric
838
        infraGenericUnranked = "Genus [ranglos] Infragen";
839
         name2 = parser.parseFullName(infraGenericUnranked);
840
        assertEquals( "Genus", name2.getGenusOrUninomial());
841
        assertEquals( null, name2.getSpecificEpithet());
842
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
843
        assertEquals( "Ranglos rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
844

    
845
    }
846

    
847
    @Test
848
    public final void testOldRanks() {
849
        try {
850
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
851
            testName_StringNomcodeRank(parseMethod);
852
        } catch (Exception e) {
853
            e.printStackTrace();
854
            assertTrue(false);
855
        }
856

    
857
        //proles
858
        String infraspecificUnranked = "Genus species proles infraspecific";
859
        INonViralName name = parser.parseFullName(infraspecificUnranked);
860
        assertEquals( "Genus", name.getGenusOrUninomial());
861
        assertEquals( "species", name.getSpecificEpithet());
862
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
863
        assertEquals( "Proles should be parsed", Rank.PROLES(), name.getRank());
864

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

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

    
882
    @Test
883
    public final void testTemp(){
884

    
885
//        String nameStr = "Mentha aquatica L. x Mentha spicata L.";
886
//        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
887
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
888
//        assertFalse( name.getHybridChildRelations().isEmpty());
889
//        for (HybridRelationship rel : name.getHybridChildRelations()){
890
//            TaxonName parent = rel.getParentName();
891
//            System.out.println(parent.getTitleCache());
892
//        }
893
    }
894

    
895

    
896
    @Test
897
    public final void testHybridsRemoval(){
898
        //if the parser input already has hybridrelationships they need to be removed
899
        //Create input
900
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
901
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
902
        assertFalse("Name must not have parsing problems", name1.hasProblem());
903
        assertTrue("", name1.getHybridChildRelations().size() == 2);
904

    
905
        hybridCache = "Abieta albana "+UTF8.HYBRID+" Pinuta custa";
906
        boolean makeEmpty = true;
907
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
908
        assertEquals("After parsing another string there should still be 2 parents, but different ones", 2, name1.getHybridChildRelations().size());
909
        assertFalse("Name must not have parsing problems", name1.hasProblem());
910

    
911

    
912
        hybridCache = "Calendula arvensis Mill.";
913
        makeEmpty = true;
914
        parser.parseFullName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
915
        assertTrue("", name1.getHybridChildRelations().isEmpty());
916
        assertFalse("Name must not have parsing problems", name1.hasProblem());
917

    
918

    
919
        //AND the same for reference parsing
920
        hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
921
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
922
        assertFalse("Name must not have parsing problems", name1.hasProblem());
923
        assertTrue("", name1.getHybridChildRelations().size() == 2);
924

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

    
931

    
932
        hybridCache = "Calendula arvensis Mill.";
933
        makeEmpty = true;
934
        parser.parseReferencedName(name1, hybridCache, Rank.SPECIES(), makeEmpty);
935
        assertTrue("", name1.getHybridChildRelations().isEmpty());
936
        assertFalse("Name must not have parsing problems", name1.hasProblem());
937
    }
938

    
939
    private void testName_StringNomcodeRank(Method parseMethod)
940
            throws InvocationTargetException, IllegalAccessException  {
941
        INonViralName name1 = (INonViralName)parseMethod.invoke(parser, strNameAbies1, null, Rank.SPECIES());
942
        //parser.parseFullName(strNameAbies1, null, Rank.SPECIES());
943
        assertEquals("Abies", name1.getGenusOrUninomial());
944
        assertEquals("alba", name1.getSpecificEpithet());
945

    
946
        INonViralName nameAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesAuthor1, null, Rank.SPECIES());
947
        assertEquals("Abies", nameAuthor.getGenusOrUninomial());
948
        assertEquals("alba", nameAuthor.getSpecificEpithet());
949
        assertEquals("Mueller", nameAuthor.getCombinationAuthorship().getNomenclaturalTitle());
950

    
951
        INonViralName nameBasionymAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymAuthor1, null, Rank.SPECIES());
952
        assertEquals("Abies", nameBasionymAuthor.getGenusOrUninomial());
953
        assertEquals("alba", nameBasionymAuthor.getSpecificEpithet());
954
        assertEquals("D'Mueller", nameBasionymAuthor.getCombinationAuthorship().getNomenclaturalTitle());
955
        assertEquals("Ciardelli", nameBasionymAuthor.getBasionymAuthorship().getNomenclaturalTitle());
956

    
957
        INonViralName nameBasionymExAuthor = (INonViralName)parseMethod.invoke(parser, strNameAbiesBasionymExAuthor1, null, Rank.SPECIES());
958
        assertEquals("Abies", nameBasionymExAuthor.getGenusOrUninomial());
959
        assertEquals("alba", nameBasionymExAuthor.getSpecificEpithet());
960
        assertEquals("D'Mueller", nameBasionymExAuthor.getExCombinationAuthorship().getNomenclaturalTitle());
961
        assertEquals("de Greuther", nameBasionymExAuthor.getCombinationAuthorship().getNomenclaturalTitle());
962
        assertEquals("Ciardelli", nameBasionymExAuthor.getExBasionymAuthorship().getNomenclaturalTitle());
963
        assertEquals("Doering", nameBasionymExAuthor.getBasionymAuthorship().getNomenclaturalTitle());
964

    
965
        INonViralName name2 = (INonViralName)parseMethod.invoke(parser, strNameAbiesSub1, null, Rank.SPECIES());
966
        assertEquals("Abies", name2.getGenusOrUninomial());
967
        assertEquals("alba", name2.getSpecificEpithet());
968
        assertEquals("beta", name2.getInfraSpecificEpithet());
969
        assertEquals(Rank.SUBSPECIES(), name2.getRank());
970

    
971

    
972
        // unparseable *********
973
        String problemString = "sdfjlös wer eer wer";
974
        INonViralName nameProblem = (INonViralName)parseMethod.invoke(parser, problemString, null, Rank.SPECIES());
975
        List<ParserProblem> list = nameProblem.getParsingProblems();
976
        assertTrue(nameProblem.getParsingProblem()!=0);
977
        assertEquals(problemString, nameProblem.getTitleCache());
978
    }
979

    
980

    
981
    /**
982
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
983
     */
984
    @Test
985
    public final void testParseNomStatus() {
986
        //nom. ambig.
987
        String strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. ambig.";
988
        INonViralName nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
989
        assertFullRefStandard(nameTestStatus);
990
        assertTrue(nameTestStatus.getStatus().size()== 1);
991
        assertEquals( NomenclaturalStatusType.AMBIGUOUS(), nameTestStatus.getStatus().iterator().next().getType());
992

    
993
        //nom. inval.
994
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. inval.";
995
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
996
        assertFullRefStandard(nameTestStatus);
997
        assertTrue(nameTestStatus.getStatus().size()== 1);
998
        assertEquals( NomenclaturalStatusType.INVALID(), nameTestStatus.getStatus().iterator().next().getType());
999

    
1000
        //nom. dub.
1001
        strTestStatus = "Abies alba Mill., Sp. Pl. 4: 455. 1987, nom. dub.";
1002
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1003
        assertFullRefStandard(nameTestStatus);
1004
        assertTrue(nameTestStatus.getStatus().size()== 1);
1005
        assertEquals( NomenclaturalStatusType.DOUBTFUL(), nameTestStatus.getStatus().iterator().next().getType());
1006

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1189
        //ined.
1190
        strTestStatus = "Houstonia macvaughii (Terrell), ined.";
1191
        nameTestStatus = parser.parseReferencedName(strTestStatus, null, Rank.SPECIES());
1192
        assertEquals("Houstonia", nameTestStatus.getGenusOrUninomial());
1193
        assertEquals("macvaughii", nameTestStatus.getSpecificEpithet());
1194
        assertEquals("(Terrell)", nameTestStatus.getAuthorshipCache());
1195
        assertEquals(1, nameTestStatus.getStatus().size());
1196
        assertEquals( NomenclaturalStatusType.INED(), nameTestStatus.getStatus().iterator().next().getType());
1197

    
1198
        //not yet parsed "not avail."
1199
    }
1200

    
1201
    /**
1202
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseReferencedName(NonViralName, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, boolean)(, )}.
1203
     */
1204
    @Test
1205
    public final void testParseReferencedName() {
1206
        try {
1207
            Method parseMethod = parser.getClass().getDeclaredMethod("parseReferencedName", String.class, NomenclaturalCode.class, Rank.class);
1208
            testName_StringNomcodeRank(parseMethod);
1209
        } catch (Exception e) {
1210
            e.printStackTrace();
1211
            assertTrue(false);
1212
        }
1213

    
1214
        //null
1215
        String strNull = null;
1216
        Rank rankSpecies = Rank.SPECIES();
1217
        INonViralName nameNull = parser.parseReferencedName(strNull, null, rankSpecies);
1218
        assertNull(nameNull);
1219

    
1220
        //Empty
1221
        String strEmpty = "";
1222
        INonViralName nameEmpty = parser.parseReferencedName(strEmpty, null, rankSpecies);
1223
        assertFalse(nameEmpty.hasProblem());
1224
        assertEquals(strEmpty, nameEmpty.getFullTitleCache());
1225
        assertNull(nameEmpty.getNomenclaturalMicroReference());
1226

    
1227

    
1228
        //Whitespaces
1229
        String strFullWhiteSpcaceAndDot = "Abies alba Mill.,  Sp.   Pl.  4:  455 .  1987 .";
1230
        INonViralName namefullWhiteSpcaceAndDot = parser.parseReferencedName(strFullWhiteSpcaceAndDot, null, rankSpecies);
1231
        assertFullRefStandard(namefullWhiteSpcaceAndDot);
1232
        assertTrue(namefullWhiteSpcaceAndDot.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1233
        assertEquals( "Abies alba Mill., Sp. Pl. 4: 455. 1987", namefullWhiteSpcaceAndDot.getFullTitleCache());
1234

    
1235
        //Book
1236
        String fullReference = "Abies alba Mill., Sp. Pl. 4: 455. 1987";
1237
        INonViralName name1 = parser.parseReferencedName(fullReference, null, rankSpecies);
1238
        assertFullRefStandard(name1);
1239
        assertTrue(name1.getNomenclaturalReference().getType().equals(eu.etaxonomy.cdm.model.reference.ReferenceType.Book));
1240
        assertEquals(fullReference, name1.getFullTitleCache());
1241
        assertTrue("Name author and reference author should be the same", name1.getCombinationAuthorship() == name1.getNomenclaturalReference().getAuthorship());
1242

    
1243
        //Book Section
1244
        fullReference = "Abies alba Mill. in Otto, Sp. Pl. 4(6): 455. 1987";
1245
        INonViralName name2 = parser.parseReferencedName(fullReference + ".", null, rankSpecies);
1246
        assertFullRefNameStandard(name2);
1247
        assertEquals(fullReference, name2.getFullTitleCache());
1248
        assertFalse(name2.hasProblem());
1249
        INomenclaturalReference ref = name2.getNomenclaturalReference();
1250
        assertEquals(ReferenceType.BookSection, ((Reference)ref).getType());
1251
        IBookSection bookSection = (IBookSection) ref;
1252
        IBook inBook = bookSection.getInBook();
1253
        assertNotNull(inBook);
1254
        assertNotNull(inBook.getAuthorship());
1255
        assertEquals("Otto", inBook.getAuthorship().getTitleCache());
1256
        assertEquals("Otto, Sp. Pl. 4(6)", inBook.getTitleCache());
1257
        assertEquals("Sp. Pl.", inBook.getAbbrevTitle());
1258
        assertEquals("4(6)", inBook.getVolume());
1259
        assertTrue("Name author and reference author should be the same", name2.getCombinationAuthorship() == name2.getNomenclaturalReference().getAuthorship());
1260

    
1261
        //Article
1262
        fullReference = "Abies alba Mill. in Sp. Pl. 4(6): 455. 1987";
1263
        INonViralName name3 = parser.parseReferencedName(fullReference, null, rankSpecies);
1264
        assertFullRefNameStandard(name3);
1265
        name3.setTitleCache(null);
1266
        assertEquals(fullReference, name3.getFullTitleCache());
1267
        assertFalse(name3.hasProblem());
1268
        ref = name3.getNomenclaturalReference();
1269
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1270
        //Article article = (Article)ref;
1271
        IJournal journal = ((IArticle)ref).getInJournal();
1272
        assertNotNull(journal);
1273
        //assertEquals("Sp. Pl. 4(6)", inBook.getTitleCache());
1274
        assertEquals("Sp. Pl.",((Reference) journal).getTitleCache());
1275
        assertEquals("Sp. Pl.", journal.getAbbrevTitle());
1276
        assertEquals("4(6)",((IArticle)ref).getVolume());
1277
        assertTrue("Name author and reference author should be the same", name3.getCombinationAuthorship() == name3.getNomenclaturalReference().getAuthorship());
1278

    
1279
        //Article with volume range
1280
        fullReference = "Abies alba Mill. in Sp. Pl. 4(1-2): 455. 1987";
1281
        INonViralName name3a = parser.parseReferencedName(fullReference, null, rankSpecies);
1282
        name3a.setTitleCache(null);
1283
        assertEquals(fullReference, name3a.getFullTitleCache());
1284
        assertFalse(name3a.hasProblem());
1285
        ref = name3a.getNomenclaturalReference();
1286
        assertEquals(eu.etaxonomy.cdm.model.reference.ReferenceType.Article, ref.getType());
1287
        assertEquals("4(1-2)",((IArticle)ref).getVolume());
1288

    
1289
        //SoftArticle - having "," on position > 4
1290
        String journalTitle = "Bull. Soc. Bot.France. Louis., Roi";
1291
        String yearPart = " 1987 - 1989";
1292
        String parsedYear = "1987-1989";
1293
        String parsedYearFormatted = "1987"+SEP+"1989";
1294
        String fullReferenceWithoutYear = "Abies alba Mill. in " + journalTitle + " 4(6): 455.";
1295
        fullReference = fullReferenceWithoutYear + yearPart;
1296
        String fullReferenceWithEnd = fullReference + ".";
1297
        INonViralName name4 = parser.parseReferencedName(fullReferenceWithEnd, null, rankSpecies);
1298
        assertFalse(name4.hasProblem());
1299
        assertFullRefNameStandard(name4);
1300
        assertEquals(fullReferenceWithoutYear + " " + parsedYearFormatted, name4.getFullTitleCache());
1301
        ref = name4.getNomenclaturalReference();
1302
        assertEquals(ReferenceType.Article, ref.getType());
1303
        //article = (Article)ref;
1304
        assertEquals(parsedYearFormatted, ref.getYear());
1305
        journal = ((IArticle)ref).getInJournal();
1306
        assertNotNull(journal);
1307
        assertEquals(journalTitle, ((Reference) journal).getTitleCache());
1308
        assertEquals(journalTitle, journal.getAbbrevTitle());
1309
        assertEquals("4(6)", ((IArticle)ref).getVolume());
1310

    
1311
        //Zoo name
1312
        String strNotParsableZoo = "Abies alba M., 1923, Sp. P. xxwer4352, nom. inval.";
1313
        IZoologicalName nameZooRefNotParsabel = parser.parseReferencedName(strNotParsableZoo, null, null);
1314
        assertTrue(nameZooRefNotParsabel.hasProblem());
1315
        List<ParserProblem> list = nameZooRefNotParsabel.getParsingProblems();
1316
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1317
        assertEquals(21, nameZooRefNotParsabel.getProblemStarts());
1318
        assertEquals(37, nameZooRefNotParsabel.getProblemEnds());
1319
        assertTrue(nameZooRefNotParsabel.getNomenclaturalReference().hasProblem());
1320
        list = nameZooRefNotParsabel.getNomenclaturalReference().getParsingProblems();
1321
        assertTrue("List must contain detail and year warning ", list.contains(ParserProblem.CheckDetailOrYear));
1322

    
1323
        assertEquals(NomenclaturalCode.ICZN, nameZooRefNotParsabel.getNameType());
1324
        assertEquals(Integer.valueOf(1923), nameZooRefNotParsabel.getPublicationYear());
1325
        assertEquals(1, nameZooRefNotParsabel.getStatus().size());
1326

    
1327
        String strZooNameSineYear = "Homo sapiens L., 1758, Sp. An. 3: 345";
1328
        IZoologicalName nameZooNameSineYear = parser.parseReferencedName(strZooNameSineYear);
1329
        assertFalse(nameZooNameSineYear.hasProblem());
1330
        assertEquals("Name without reference year must have year", (Integer)1758, nameZooNameSineYear.getPublicationYear());
1331
        assertEquals("Name without reference year must have year", "1758", nameZooNameSineYear.getNomenclaturalReference().getYear());
1332

    
1333
        String strZooNameNewCombination = "Homo sapiens (L., 1758) Mill., 1830, Sp. An. 3: 345";
1334
        IZoologicalName nameZooNameNewCombination = parser.parseReferencedName(strZooNameNewCombination);
1335
        assertTrue(nameZooNameNewCombination.hasProblem());
1336
        list = nameZooNameNewCombination.getParsingProblems();
1337
        assertTrue("List must contain new combination has publication warning ", list.contains(ParserProblem.NewCombinationHasPublication));
1338
        assertEquals(35, nameZooNameNewCombination.getProblemStarts());
1339
        assertEquals(51, nameZooNameNewCombination.getProblemEnds());
1340

    
1341
        //Special MicroRefs
1342
        String strSpecDetail1 = "Abies alba Mill. in Sp. Pl. 4(6): [455]. 1987";
1343
        INonViralName nameSpecDet1 = parser.parseReferencedName(strSpecDetail1 + ".", null, rankSpecies);
1344
        assertFalse(nameSpecDet1.hasProblem());
1345
        assertEquals(strSpecDetail1, nameSpecDet1.getFullTitleCache());
1346
        assertEquals("[455]", nameSpecDet1.getNomenclaturalMicroReference());
1347

    
1348
        //Special MicroRefs
1349
        String strSpecDetail2 = "Abies alba Mill. in Sp. Pl. 4(6): couv. 2. 1987";
1350
        INonViralName nameSpecDet2 = parser.parseReferencedName(strSpecDetail2 + ".", null, rankSpecies);
1351
        assertFalse(nameSpecDet2.hasProblem());
1352
        assertEquals(strSpecDetail2, nameSpecDet2.getFullTitleCache());
1353
        assertEquals("couv. 2", nameSpecDet2.getNomenclaturalMicroReference());
1354

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

    
1362
        //Special MicroRefs
1363
        String strSpecDetail4 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455-567. 1987";
1364
        fullReference = strSpecDetail4 + ".";
1365
        INonViralName nameSpecDet4 = parser.parseReferencedName(fullReference, null, rankSpecies);
1366
        assertFalse(nameSpecDet4.hasProblem());
1367
        assertEquals(strSpecDetail4, nameSpecDet4.getFullTitleCache());
1368
        assertEquals("fig. 455-567", nameSpecDet4.getNomenclaturalMicroReference());
1369

    
1370
        //Special MicroRefs
1371
        String strSpecDetail5 = "Abies alba Mill. in Sp. Pl. 4(6): Gard n\u00B0 4. 1987";
1372
        fullReference = strSpecDetail5 + ".";
1373
        INonViralName nameSpecDet5 = parser.parseReferencedName(fullReference, null, rankSpecies);
1374
        assertFalse(nameSpecDet5.hasProblem());
1375
        assertEquals(strSpecDetail5, nameSpecDet5.getFullTitleCache());
1376
        assertEquals("Gard n\u00B0 4", nameSpecDet5.getNomenclaturalMicroReference());
1377

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

    
1386
        //Special MicroRefs
1387
        String strSpecDetail7 = "Abies alba Mill. in Sp. Pl. 4(6): pp.455-457. 1987";
1388
        fullReference = strSpecDetail7 + ".";
1389
        INonViralName nameSpecDet7 = parser.parseReferencedName(fullReference, null, rankSpecies);
1390
        assertFalse(nameSpecDet7.hasProblem());
1391
        assertEquals(strSpecDetail7, nameSpecDet7.getFullTitleCache());
1392
        assertEquals("pp.455-457", nameSpecDet7.getNomenclaturalMicroReference());
1393

    
1394
        //Special MicroRefs
1395
        String strSpecDetail8 = "Abies alba Mill. in Sp. Pl. 4(6): ppp.455-457. 1987";
1396
        INonViralName nameSpecDet8 = parser.parseReferencedName(strSpecDetail8, null, rankSpecies);
1397
        assertTrue(nameSpecDet8.hasProblem());
1398
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1399
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after -457
1400

    
1401

    
1402
        //Special MicroRefs
1403
        String strSpecDetail9 = "Abies alba Mill. in Sp. Pl. 4(6): pp. 455 - 457. 1987";
1404
        INonViralName nameSpecDet9 = parser.parseReferencedName(strSpecDetail9, null, rankSpecies);
1405
        assertFalse(nameSpecDet9.hasProblem());
1406
        assertEquals(strSpecDetail9, nameSpecDet9.getFullTitleCache());
1407
        assertEquals("pp. 455 - 457", nameSpecDet9.getNomenclaturalMicroReference());
1408

    
1409
        //Special MicroRefs
1410
        String strSpecDetail10 = "Abies alba Mill. in Sp. Pl. 4(6): p 455. 1987";
1411
        INonViralName nameSpecDet10 = parser.parseReferencedName(strSpecDetail10, null, rankSpecies);
1412
        assertFalse(nameSpecDet10.hasProblem());
1413
        assertEquals(strSpecDetail10, nameSpecDet10.getFullTitleCache());
1414
        assertEquals("p 455", nameSpecDet10.getNomenclaturalMicroReference());
1415

    
1416
        //Special MicroRefs
1417
        String strSpecDetail11 = "Abies alba Mill. in Sp. Pl. 4(6): p. 455 - 457. 1987";
1418
        INonViralName nameSpecDet11 = parser.parseReferencedName(strSpecDetail11, null, rankSpecies);
1419
        assertTrue(nameSpecDet11.hasProblem());
1420
        list = nameSpecDet11.getParsingProblems();
1421
        assertTrue("Problem is Detail. Must be pp.", list.contains(ParserProblem.CheckDetailOrYear));
1422
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1423
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after - 457
1424

    
1425

    
1426
        //no volume, no edition
1427
        String strNoVolume = "Abies alba Mill., Sp. Pl.: 455. 1987";
1428
        INonViralName nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1429
        assertFalse(nameNoVolume.hasProblem());
1430
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1431
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1432
        assertEquals(null, ((IBook)nameNoVolume.getNomenclaturalReference()).getEdition());
1433

    
1434
        //volume, no edition
1435
        strNoVolume = "Abies alba Mill., Sp. Pl. 2: 455. 1987";
1436
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1437
        assertFalse(nameNoVolume.hasProblem());
1438
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1439
        assertEquals("2", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1440
        assertEquals(null, ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1441

    
1442
        //no volume, edition
1443
        strNoVolume = "Abies alba Mill., Sp. Pl., ed. 3: 455. 1987";
1444
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1445
        assertFalse(nameNoVolume.hasProblem());
1446
        assertEquals(strNoVolume, nameNoVolume.getFullTitleCache());
1447
        assertEquals(null, ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1448
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1449

    
1450
        //volume, edition
1451
        strNoVolume = "Abies alba Mill., Sp. Pl. ed. 3, 4(5): 455. 1987";
1452
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1453
        assertFalse(nameNoVolume.hasProblem());
1454
        assertEquals(strNoVolume.replace(" ed.", ", ed."), nameNoVolume.getFullTitleCache());
1455
        assertEquals("4(5)", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1456
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1457

    
1458
        String strUnparsableInRef = "Abies alba Mill. in -er46: 455. 1987";
1459
        INonViralName nameUnparsableInRef = parser.parseReferencedName(strUnparsableInRef, null, rankSpecies);
1460
        assertTrue(nameUnparsableInRef.hasProblem());
1461
        list = nameUnparsableInRef.getParsingProblems();
1462
        assertTrue("Unparsable title", list.contains(ParserProblem.UnparsableReferenceTitle));
1463
        assertEquals(strUnparsableInRef, nameUnparsableInRef.getFullTitleCache());
1464
        assertEquals(20, nameUnparsableInRef.getProblemStarts());
1465
        assertEquals(25, nameUnparsableInRef.getProblemEnds());
1466

    
1467

    
1468
        //volume, edition
1469
        String strNoSeparator = "Abies alba Mill. Sp. Pl. ed. 3, 4(5): 455. 1987";
1470
        INonViralName nameNoSeparator = parser.parseReferencedName(strNoSeparator, ICNAFP, rankSpecies);
1471
        assertTrue(nameNoSeparator.hasProblem());
1472
        list = nameNoSeparator.getParsingProblems();
1473
        assertTrue("Problem is missing name-reference separator", list.contains(ParserProblem.NameReferenceSeparation));
1474
        assertEquals(strNoSeparator, nameNoSeparator.getFullTitleCache());
1475
        assertEquals(10, nameNoSeparator.getProblemStarts()); //TODO better start behind Mill. (?)
1476
        assertEquals(47, nameNoSeparator.getProblemEnds());   //TODO better stop before :
1477

    
1478
        String strUnparsableInRef2 = "Hieracium pepsicum L., My Bookkkk 1. 1903";
1479
        INonViralName nameUnparsableInRef2 = parser.parseReferencedName(strUnparsableInRef2, null, rankSpecies);
1480
        assertTrue(nameUnparsableInRef2.hasProblem());
1481
        list = nameUnparsableInRef2.getParsingProblems();
1482
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1483
        assertEquals(strUnparsableInRef2, nameUnparsableInRef2.getFullTitleCache());
1484
        assertEquals(23, nameUnparsableInRef2.getProblemStarts());
1485
        assertEquals(41, nameUnparsableInRef2.getProblemEnds());
1486

    
1487

    
1488
        String strUnparsableInRef3 = "Hieracium pespcim N., My Bookkkk 1. 1902";
1489
        INonViralName nameUnparsableInRef3 = parser.parseReferencedName(strUnparsableInRef3, null, null);
1490
        assertTrue(nameUnparsableInRef3.hasProblem());
1491
        list = nameUnparsableInRef3.getParsingProblems();
1492
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1493
        assertEquals(strUnparsableInRef3, nameUnparsableInRef3.getFullTitleCache());
1494
        assertEquals(22, nameUnparsableInRef3.getProblemStarts());
1495
        assertEquals(40, nameUnparsableInRef3.getProblemEnds());
1496

    
1497
        String strUnparsableInRef4 = "Hieracium pepsicum (Hsllreterto) L., My Bookkkk 1. 1903";
1498
        INonViralName nameUnparsableInRef4 = parser.parseReferencedName(strUnparsableInRef4, null, null);
1499
        assertTrue(nameUnparsableInRef4.hasProblem());
1500
        list = nameUnparsableInRef4.getParsingProblems();
1501
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1502
        assertEquals(strUnparsableInRef4, nameUnparsableInRef4.getFullTitleCache());
1503
        assertEquals(37, nameUnparsableInRef4.getProblemStarts());
1504
        assertEquals(55, nameUnparsableInRef4.getProblemEnds());
1505

    
1506
        String strSameName = "Hieracium pepcum (Hsllreterto) L., My Bokkk 1. 1903";
1507
        INonViralName nameSameName = nameUnparsableInRef4;
1508
        parser.parseReferencedName(nameSameName, strSameName, null, true);
1509
        assertTrue(nameSameName.hasProblem());
1510
        list = nameSameName.getParsingProblems();
1511
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1512
        assertEquals(strSameName, nameSameName.getFullTitleCache());
1513
        assertEquals(35, nameSameName.getProblemStarts());
1514
        assertEquals(51, nameSameName.getProblemEnds());
1515

    
1516
        String strGenusUnparse = "Hieracium L., jlklk";
1517
        INonViralName nameGenusUnparse =
1518
            parser.parseReferencedName(strGenusUnparse, null, null);
1519
        assertTrue(nameGenusUnparse.hasProblem());
1520
        list = nameGenusUnparse.getParsingProblems();
1521
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1522
        assertTrue("Problem uninomial", list.contains(ParserProblem.CheckRank));
1523
        assertEquals(strGenusUnparse, nameGenusUnparse.getFullTitleCache());
1524
        assertEquals(0, nameGenusUnparse.getProblemStarts());
1525
        assertEquals(19, nameGenusUnparse.getProblemEnds());
1526

    
1527
        String strGenusUnparse2 = "Hieracium L., Per Luigi: 44. 1987";
1528
        INonViralName nameGenusUnparse2 =
1529
            parser.parseReferencedName(strGenusUnparse2, null, Rank.FAMILY());
1530
        assertFalse(nameGenusUnparse2.hasProblem());
1531
        assertEquals(strGenusUnparse2, nameGenusUnparse2.getFullTitleCache());
1532
        assertEquals(-1, nameGenusUnparse2.getProblemStarts());
1533
        assertEquals(-1, nameGenusUnparse2.getProblemEnds());
1534

    
1535
        String strBookSection2 = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz, ed. 2, 2: 288. 1905-1907";
1536
        String strBookSection2NoComma = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905-1907";
1537
        INonViralName nameBookSection2 =
1538
              parser.parseReferencedName(strBookSection2, null, null);
1539
        assertFalse(nameBookSection2.hasProblem());
1540
        nameBookSection2.setFullTitleCache(null, false);
1541
        assertEquals(strBookSection2NoComma.replace(" ed.", ", ed.").replace("-",SEP), nameBookSection2.getFullTitleCache());
1542
        assertEquals(-1, nameBookSection2.getProblemStarts());
1543
        assertEquals(-1, nameBookSection2.getProblemEnds());
1544
        assertNull((nameBookSection2.getNomenclaturalReference()).getDatePublished().getStart());
1545
        assertEquals("1905"+SEP+"1907", ((IBookSection)nameBookSection2.getNomenclaturalReference()).getInBook().getDatePublished().getYear());
1546

    
1547
        String strBookSection = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905";
1548
        INonViralName nameBookSection =
1549
            parser.parseReferencedName(strBookSection, null, null);
1550
        assertFalse(nameBookSection.hasProblem());
1551
        assertEquals(strBookSection.replace(" ed.", ", ed."), nameBookSection.getFullTitleCache());
1552
        assertEquals(-1, nameBookSection.getProblemStarts());
1553
        assertEquals(-1, nameBookSection.getProblemEnds());
1554
        assertNull(((IBookSection)nameBookSection.getNomenclaturalReference()).getInBook().getDatePublished().getStart());
1555
        assertEquals("1905", ((IBookSection)nameBookSection.getNomenclaturalReference()).getDatePublished().getYear());
1556

    
1557
        String strXXXs = "Abies alba, Soer der 1987";
1558
        INonViralName problemName = parser.parseReferencedName(strXXXs, null, null);
1559
        assertTrue(problemName.hasProblem());
1560
        list = problemName.getParsingProblems();
1561
        assertTrue("Problem must be name-reference separation", list.contains(ParserProblem.NameReferenceSeparation));
1562
        parser.parseReferencedName(problemName, strBookSection, null, true);
1563
        assertFalse(problemName.hasProblem());
1564

    
1565
        problemName = parser.parseFullName(strXXXs, null, null);
1566
        assertTrue(problemName.hasProblem());
1567
        list = problemName.getParsingProblems();
1568
        assertTrue("Name part must be unparsable", list.contains(ParserProblem.UnparsableNamePart));
1569

    
1570

    
1571
        String testParsable = "Pithecellobium macrostachyum Benth.";
1572
        assertTrue(isParsable(testParsable, ICNAFP));
1573

    
1574
        testParsable = "Pithecellobium macrostachyum (Benth.)";
1575
        assertTrue(isParsable(testParsable, ICNAFP));
1576

    
1577
        testParsable = "Pithecellobium macrostachyum (Benth., 1845)";
1578
        assertTrue(isParsable(testParsable, NomenclaturalCode.ICZN));
1579

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

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

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

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

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

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

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

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

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

    
1611
        testParsable = "Hieracium lachenalii, Ill. Fl. (Mitt.) 6: 1285. 1929";
1612
        assertFalse("Author is obligatory if followed by reference", isParsable(testParsable, ICNAFP));
1613
        assertTrue("Problem must be name-reference separation", getProblems(testParsable, ICNAFP).
1614
                contains(ParserProblem.NameReferenceSeparation));
1615

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

    
1621
        testParsable = "Abies alba Mill. var. alba";
1622
        assertTrue("Autonym problem", isParsable(testParsable, ICNAFP));
1623

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

    
1627

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

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

    
1635

    
1636
    }
1637

    
1638

    
1639
    /**
1640
     * Test author with name parts van, von, de, de la, d', da, del.
1641
     * See also http://dev.e-taxonomy.eu/trac/ticket/3373
1642
     */
1643
    @Test
1644
    public final void  testComposedAuthorNames(){
1645

    
1646
        //van author (see https://dev.e-taxonomy.eu/trac/ticket/3373)
1647
        String testParsable = "Aphelocoma unicolor subsp. griscomi van Rossem, 1928";
1648
        assertTrue("Author with 'van' should be parsable", isParsable(testParsable, ICZN));
1649

    
1650
        //von author (see https://dev.e-taxonomy.eu/trac/ticket/3373)
1651
        testParsable = "Aphelocoma unicolor subsp. griscomi von Rossem, 1928";
1652
        assertTrue("Author with 'von' should be parsable", isParsable(testParsable, ICZN));
1653

    
1654
        //de author (see https://dev.e-taxonomy.eu/trac/ticket/3373)
1655
        testParsable = "Aphelocoma unicolor subsp. griscomi de Rossem, 1928";
1656
        assertTrue("Author with 'de' should be parsable", isParsable(testParsable, ICZN));
1657

    
1658
        //de la author (see https://dev.e-taxonomy.eu/trac/ticket/3373)
1659
        testParsable = "Aphelocoma unicolor subsp. griscomi de la Rossem, 1928";
1660
        assertTrue("Author with 'de la' should be parsable", isParsable(testParsable, ICZN));
1661

    
1662
        //d' author (see https://dev.e-taxonomy.eu/trac/ticket/3373)
1663
        testParsable = "Aphelocoma unicolor subsp. griscomi d'Rossem, 1928";
1664
        assertTrue("Author with \"'d'\" should be parsable", isParsable(testParsable, ICZN));
1665

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

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

    
1674
        //O' author (see https://dev.e-taxonomy.eu/trac/ticket/4759)
1675
        testParsable = "Aphelocoma unicolor subsp. griscomi O'Connor, 1928";
1676
        assertTrue("Author with 'O'' should be parsable", isParsable(testParsable, ICZN));
1677

    
1678
        //del author (see https://dev.e-taxonomy.eu/trac/ticket/4759)
1679
        testParsable = "Aphelocoma unicolor subsp. griscomi zur Strassen, 1928";
1680
        assertTrue("Author with 'zur' should be parsable", isParsable(testParsable, ICZN));
1681

    
1682
    }
1683

    
1684

    
1685

    
1686
    /**
1687
     * @param testParsable
1688
     * @param icbn
1689
     * @return
1690
     */
1691
    private List<ParserProblem> getProblems(String string, NomenclaturalCode code) {
1692
        List<ParserProblem> result = parser.parseReferencedName(string, code, null).getParsingProblems();
1693
        return result;
1694
    }
1695

    
1696
    private boolean isParsable(String string, NomenclaturalCode code){
1697
        INonViralName name = parser.parseReferencedName(string, code, null);
1698
        return ! name.hasProblem();
1699
    }
1700

    
1701
    private void assertFullRefNameStandard(INonViralName name){
1702
        assertEquals("Abies", name.getGenusOrUninomial());
1703
        assertEquals("alba", name.getSpecificEpithet());
1704
        assertEquals("Mill.", name.getAuthorshipCache());
1705
        assertEquals("455", name.getNomenclaturalMicroReference());
1706
        assertNotNull(name.getNomenclaturalReference());
1707
    }
1708

    
1709
    private void assertFullRefStandard(INonViralName name){
1710
        assertEquals("Abies", name.getGenusOrUninomial());
1711
        assertEquals("alba", name.getSpecificEpithet());
1712
        assertEquals("Mill.", name.getAuthorshipCache());
1713
        assertEquals("455", name.getNomenclaturalMicroReference());
1714
        assertNotNull(name.getNomenclaturalReference());
1715
        INomenclaturalReference ref = name.getNomenclaturalReference();
1716
        assertEquals("1987", ref.getYear());
1717
        assertEquals("Sp. Pl.", ref.getAbbrevTitle());
1718
    }
1719

    
1720

    
1721
    @Test
1722
    public void testNeverEndingParsing(){
1723
        //some full titles result in never ending parsing process https://dev.e-taxonomy.eu/trac/ticket/1556
1724

    
1725
        String irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1726
//      irinaExample = "Milichiidae Sharp, 1899, Insects. Part II. Uiuis Iuiui Hymenopteracontinued (Tubulifera and Aculeata), Coleoptera, Strepsiptera, Lepidoptera, Diptera, Aphaniptera, Thysanoptera, Hemiptera, Anoplura 6: 504. 1899";
1727
        INonViralName nvn = this.parser.parseReferencedName(irinaExample, NomenclaturalCode.ICZN, null);
1728
        int parsingProblem = nvn.getParsingProblem();
1729
        Assert.assertEquals("Name should have only rank warning", 1, parsingProblem);
1730
        Assert.assertEquals("Titlecache", "Milichiidae Sharp, 1899", nvn.getTitleCache());
1731
        Assert.assertEquals("If this line reached everything should be ok", "Milichiidae", nvn.getGenusOrUninomial());
1732

    
1733
        String anotherExample = "Scorzonera hispanica var. brevifolia Boiss. & Balansa in Boissier, Diagn. Pl. Orient., ser. 2 6: 119. 1859.";
1734
        nvn = this.parser.parseReferencedName(anotherExample, ICNAFP, null);
1735
        parsingProblem = nvn.getParsingProblem();
1736
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
1737
        Assert.assertEquals("Titlecache", "Scorzonera hispanica var. brevifolia Boiss. & Balansa", nvn.getTitleCache());
1738
        Assert.assertEquals("If this line reached everything should be ok", "Scorzonera", nvn.getGenusOrUninomial());
1739

    
1740
        String unparsable = "Taraxacum nevskii L., Trudy Bot. Inst. Nauk S.S.S.R., Ser. 1, Fl. Sist. Vyssh. Rast. 4: 293. 1937.";
1741
//      String unparsableA = "Taraxacum nevskii L. in Trudy Bot. Inst. Nauk: 293. 1937.";
1742
        nvn = this.parser.parseReferencedName(unparsable, ICNAFP, null);
1743
        Assert.assertEquals("Titlecache", "Taraxacum nevskii L.", nvn.getTitleCache());
1744
        Assert.assertEquals("If this line reached everything should be ok", "Taraxacum", nvn.getGenusOrUninomial());
1745
        parsingProblem = nvn.getParsingProblem();
1746
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1747

    
1748
        String unparsable2 = "Hieracium pxxx Dahlst., Kongl. Svenska Vetensk. Acad. Handl. ser. 2, 26(3): 255. 1894";
1749
//      String unparsable2A = "Hieracium pxxx Dahlst., Kongl Svenska Vetensk Acad Handl, 26: 255. 1894.";
1750
        nvn = this.parser.parseReferencedName(unparsable2, ICNAFP, null);
1751
        Assert.assertEquals("Titlecache", "Hieracium pxxx Dahlst.", nvn.getTitleCache());
1752
        Assert.assertEquals("If this line reached everything should be ok", "Hieracium", nvn.getGenusOrUninomial());
1753
        parsingProblem = nvn.getParsingProblem();
1754
        Assert.assertEquals("Name should no warnings or errors", 0, parsingProblem);
1755

    
1756

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

    
1762
    }
1763

    
1764

    
1765
    @Test
1766
    public final void testSeries(){
1767
        //TODO should work also for the original string:  #9014
1768
//        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea, n.s., 9: 31. 1958";
1769
        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea Bla, n.s., 9: 31. 1958";
1770
        INonViralName name = parser.parseReferencedName(parseStr);
1771
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1772
        Reference nomRef = name.getNomenclaturalReference();
1773
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1774

    
1775
        assertEquals(ReferenceType.Article, nomRef.getType());
1776
        assertEquals(name.getNomenclaturalMicroReference(), "31");
1777
        //TODO series should be parsed and handled better
1778
        assertEquals("Nova Guinea Bla, n.s.,", nomRef.getInJournal().getAbbrevTitle());
1779
//        assertEquals("n.s.", nomRef.getSeriesPart());
1780
    }
1781

    
1782
    @Test
1783
    public final void testRussian(){
1784
        String parseStr = "Cortusa turkestanica Losinsk. in Тр. Бот. инст. Aкад. наук СССР, сер. 1, 3: 239. 1936";
1785
        INonViralName name = parser.parseReferencedName(parseStr);
1786
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1787
        Reference nomRef = name.getNomenclaturalReference();
1788
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1789

    
1790
        assertEquals(ReferenceType.Article, nomRef.getType());
1791
        assertEquals(name.getNomenclaturalMicroReference(), "239");
1792
        //TODO series should be parsed and handled better
1793
        assertEquals("Тр. Бот. инст. Aкад. наук СССР, сер. 1,", nomRef.getInJournal().getAbbrevTitle());
1794
//        assertEquals("сер. 1", nomRef.getSeriesPart());
1795
    }
1796

    
1797
    @Test
1798
    public final void testDetails(){
1799
        //s.p.
1800
        String parseStr = "Xiphion filifolium var. latifolium Baker, Gard. Chron. 1876: s.p.. 1876";
1801
        INonViralName name = parser.parseReferencedName(parseStr);
1802
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1803
        Reference nomRef = name.getNomenclaturalReference();
1804
        assertEquals(ReferenceType.Book, nomRef.getType());
1805
        assertEquals(name.getNomenclaturalMicroReference(), "s.p.");
1806

    
1807
        //roman
1808
        parseStr = "Ophrys lutea subsp. pseudospeculum (DC.) Kergu\u00e9len, Collect. Partim. Nat. 8: xv. 1993";
1809
        name = parser.parseReferencedName(parseStr);
1810
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1811
        nomRef = name.getNomenclaturalReference();
1812
        assertEquals(ReferenceType.Book, nomRef.getType());
1813
        assertEquals(name.getNomenclaturalMicroReference(), "xv");
1814

    
1815
        //n. 1
1816
        parseStr = "Olea gallica Mill., Gard. Dict. ed. 8: n. 1. 1768";
1817
        name = parser.parseReferencedName(parseStr);
1818
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1819
        nomRef = name.getNomenclaturalReference();
1820
        assertEquals(ReferenceType.Book, nomRef.getType());
1821
        assertEquals(name.getNomenclaturalMicroReference(), "n. 1");
1822

    
1823
        parseStr = "Lavandula canariensis Mill., Gard. Dict. ed. 8: Lavandula no. 4. 1768";
1824
        name = parser.parseReferencedName(parseStr);
1825
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1826
        nomRef = name.getNomenclaturalReference();
1827
        assertEquals(ReferenceType.Book, nomRef.getType());
1828
        assertEquals(name.getNomenclaturalMicroReference(), "Lavandula no. 4");
1829

    
1830
        parseStr = "Aceras anthropomorphum (Pers.) Sm. in Rees, Cycl. 39(1): Aceras n. 2. 1818";
1831
        name = parser.parseReferencedName(parseStr);
1832
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1833
        nomRef = name.getNomenclaturalReference();
1834
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1835
        assertEquals(name.getNomenclaturalMicroReference(), "Aceras n. 2");
1836

    
1837
        parseStr = "Chlorolepis Nutt. in Trans. Amer. Philos. Soc., n.s., 7: errata. 1841";
1838
        name = parser.parseReferencedName(parseStr);
1839
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1840
        nomRef = name.getNomenclaturalReference();
1841
        assertEquals(ReferenceType.Article, nomRef.getType());
1842
        assertEquals(name.getNomenclaturalMicroReference(), "errata");
1843

    
1844
        parseStr = "Yermoloffia B\u00e9l., Voy. Indes Or.: t. s.n.. 1846";
1845
        name = parser.parseReferencedName(parseStr);
1846
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1847
        nomRef = name.getNomenclaturalReference();
1848
        assertEquals(ReferenceType.Book, nomRef.getType());
1849
        assertEquals(name.getNomenclaturalMicroReference(), "t. s.n.");
1850

    
1851
        parseStr = "Gagea mauritanica Durieu, Expl. Sci. Alg\u00e9rie, Atlas: t. 45bis, f. 4. 1850";
1852
        name = parser.parseReferencedName(parseStr);
1853
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1854
        nomRef = name.getNomenclaturalReference();
1855
        assertEquals(ReferenceType.Book, nomRef.getType());
1856
        assertEquals(name.getNomenclaturalMicroReference(), "t. 45bis, f. 4");
1857

    
1858
        parseStr = "Orchis latifolia f. blyttii Rchb. f. in Reichenbach, Icon. Fl. Germ. Helv. 13-14: 60, t. 59, f. III. 1851";
1859
        name = parser.parseReferencedName(parseStr);
1860
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1861
        nomRef = name.getNomenclaturalReference();
1862
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1863
        assertEquals(name.getNomenclaturalMicroReference(), "60, t. 59, f. III");
1864

    
1865
        parseStr = "Ephedra alata var. decaisnei Stapf in Denkschr. Kaiserl. Akad. Wiss., Wien. Math.-Naturwiss. Kl. 56(2): t. 1/1. 1889";
1866
        name = parser.parseReferencedName(parseStr);
1867
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1868
        nomRef = name.getNomenclaturalReference();
1869
        assertEquals(ReferenceType.Article, nomRef.getType());
1870
        assertEquals(name.getNomenclaturalMicroReference(), "t. 1/1");
1871
    }
1872

    
1873
    @Test
1874
    public final void testEditionVolumeSeries(){
1875
        //ed. 2, 2(1)
1876
        String parseStr = "Sieberia albida (L.) Spreng., Anleit. Kenntn. Gew., ed. 2, 2(1): 282. 1817";
1877
        INonViralName name = parser.parseReferencedName(parseStr);
1878
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1879
        Reference nomRef = name.getNomenclaturalReference();
1880
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1881
        assertEquals(ReferenceType.Book, nomRef.getType());
1882
        assertEquals("2", nomRef.getEdition());
1883
        assertEquals("2(1)", nomRef.getVolume());
1884

    
1885
        parseStr = "Gagea glacialis var. joannis (Grossh.) Grossh., Fl. Kavkaza, ed. 2, 2: 105. 1940";
1886
        name = parser.parseReferencedName(parseStr);
1887
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1888
        nomRef = name.getNomenclaturalReference();
1889
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1890
        assertEquals(ReferenceType.Book, nomRef.getType());
1891
        assertEquals("2", nomRef.getEdition());
1892
        assertEquals("2", nomRef.getVolume());
1893

    
1894
        //14-15
1895
        parseStr = "Semele gayae (Webb & Berthel.) Svent. & Kunkel, Cuad. Bot. Canaria 14-15: 81. 1972";
1896
        name = parser.parseReferencedName(parseStr);
1897
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1898
        nomRef = name.getNomenclaturalReference();
1899
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1900
        assertEquals(ReferenceType.Book, nomRef.getType());
1901
        assertEquals("14-15", nomRef.getVolume());
1902

    
1903
        //35-37(2)
1904
        parseStr = "Lavandula multifida var. heterotricha Sauvage in Bull. Soc. Sci. Nat. Maroc 35-37(2): 392. 1947";
1905
        name = parser.parseReferencedName(parseStr);
1906
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1907
        nomRef = name.getNomenclaturalReference();
1908
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1909
        assertEquals(ReferenceType.Article, nomRef.getType());
1910
        assertNull(nomRef.getEdition());
1911
        assertEquals("35-37(2)", nomRef.getVolume());
1912

    
1913
        //Sér. 7
1914
        parseStr = "Oxynepeta involucrata Bunge, M\u00E9m. Acad. Imp. Sci. Saint P\u00E9tersbourg, S\u00E9r. 7, 21(1): 59. 1878";
1915
        name = parser.parseReferencedName(parseStr);
1916
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1917
        nomRef = name.getNomenclaturalReference();
1918
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1919
        assertEquals(ReferenceType.Book, nomRef.getType());
1920
        assertNull(nomRef.getEdition());
1921
        assertEquals("21(1)", nomRef.getVolume());
1922
        //Currently we do not put the series part into the series field, this may change in future
1923
//        assertEquals("Sér. 7", nomRef.getSeriesPart());
1924

    
1925
        //Suppl. 1
1926
        parseStr = "Dissorhynchium Schauer, Nov. Actorum Acad. Caes. Leop.-Carol. Nat. Cur. 19(Suppl. 1): 434. 1843";
1927
        name = parser.parseReferencedName(parseStr);
1928
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1929
        nomRef = name.getNomenclaturalReference();
1930
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1931
        assertEquals(ReferenceType.Book, nomRef.getType());
1932
        assertNull(nomRef.getEdition());
1933
        assertEquals("19(Suppl. 1)", nomRef.getVolume());
1934

    
1935
        //54*B*
1936
        parseStr = "Thymus chaubardii var. boeoticus (Heinr. Braun) Ronniger in Beih. Bot. Centralbl. 54B: 662. 1936";
1937
        name = parser.parseReferencedName(parseStr);
1938
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1939
        nomRef = name.getNomenclaturalReference();
1940
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1941
        assertEquals(ReferenceType.Article, nomRef.getType());
1942
        assertNull(nomRef.getEdition());
1943
        assertEquals("54B", nomRef.getVolume());
1944

    
1945

    
1946
        //1, Erg.
1947
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.volume);
1948
        Matcher matcher = seriesPattern.matcher("12(1, Erg.)");
1949
        Assert.assertTrue("12(1, Erg.) should match", matcher.matches());
1950

    
1951
        parseStr = "Scilla amethystina Vis. in Flora Abt Awer Ser 12(1, Erg.): 11. 1829";
1952
        name = parser.parseReferencedName(parseStr);
1953
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1954
        nomRef = name.getNomenclaturalReference();
1955
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1956
        assertEquals(ReferenceType.Article, nomRef.getType());
1957
        assertNull(nomRef.getEdition());
1958
        assertEquals("12(1, Erg.)", nomRef.getVolume());
1959

    
1960
        // jubilee ed.
1961
        parseStr = "Orchis sambucina var. bracteata (M. Schulze) Harz, Fl. Deutschl., jubilee ed., 4: 271. 1895";
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
        assertEquals("jubilee ed.",nomRef.getEdition());
1968
        assertEquals("4", nomRef.getVolume());
1969
        assertEquals(parseStr, name.getFullTitleCache());
1970

    
1971
        //nouv. ed.
1972
        parseStr = "Fraxinus polemonifolia Poir. in Duhamel du Monceau, Trait\u00E9 Arbr. Arbust., nouv. ed., 4: 66. 1809";
1973
        name = parser.parseReferencedName(parseStr);
1974
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1975
        nomRef = name.getNomenclaturalReference();
1976
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1977
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1978
        assertEquals("nouv. ed.",nomRef.getInReference().getEdition());
1979
        assertEquals("4", nomRef.getInReference().getVolume());
1980
        assertEquals(parseStr, name.getFullTitleCache());
1981

    
1982
        //ed. 3B
1983
        parseStr = "Juncus supinus var. kochii (F. W. Schultz) Syme in Smith, Engl. Bot., ed. 3B, 10: 33. 1870";
1984
        name = parser.parseReferencedName(parseStr);
1985
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1986
        nomRef = name.getNomenclaturalReference();
1987
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
1988
        assertEquals(ReferenceType.BookSection, nomRef.getType());
1989
        //maybe we remove ed. for this case in future
1990
        assertEquals("ed. 3B",nomRef.getInReference().getEdition());
1991
        assertEquals("10", nomRef.getInReference().getVolume());
1992
        assertEquals(parseStr, name.getFullTitleCache());
1993

    
1994
        //ed. 15 bis
1995
        parseStr = "Solanum persicum Willd. ex Roem. & Schult., Syst. Veg., ed. 15 bis, 4: 662. 1819";
1996
        name = parser.parseReferencedName(parseStr);
1997
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1998
        nomRef = name.getNomenclaturalReference();
1999
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2000
        assertEquals(ReferenceType.Book, nomRef.getType());
2001
        //maybe we remove ed. for this case in future
2002
        assertEquals("ed. 15 bis",nomRef.getEdition());
2003
        assertEquals("4", nomRef.getVolume());
2004
        assertEquals(parseStr, name.getFullTitleCache());
2005

    
2006

    
2007
//        Epipactis helleborine subsp. ohwii (Fukuy.) H. J. Su in Fl. Taiwan, ed. 2, 5: 861. 2000
2008
    }
2009

    
2010
    @Test
2011
    public final void testTitleBrackets(){
2012
        //Bot. Zhurn. (Moscow & Leningrad)
2013
        String parseStr = "Juncus subcompressus Zakirov & Novopokr. in Bot. Zhurn. (Moscow & Leningrad) 36(1): 77. 1951";
2014
        TaxonName name = parser.parseReferencedName(parseStr);
2015
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2016
        Reference nomRef = name.getNomenclaturalReference();
2017
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2018
        assertEquals(ReferenceType.Article, nomRef.getType());
2019
        assertEquals("Bot. Zhurn. (Moscow & Leningrad)", nomRef.getInReference().getAbbrevTitle());
2020
        assertNull(nomRef.getEdition());
2021
        assertEquals("36(1)", nomRef.getVolume());
2022
    }
2023

    
2024
    @Test
2025
    public final void testTitleSpecials(){
2026
        //Pt. 2  (currently handled as series part, may change in future
2027
        String parseStr = "Iris pumila subsp. sintenisiiformis Prod\u00E1n in Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat. 27: 89. 1941";
2028
        TaxonName name = parser.parseReferencedName(parseStr);
2029
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2030
        Reference nomRef = name.getNomenclaturalReference();
2031
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2032
        assertEquals(ReferenceType.Article, nomRef.getType());
2033
        assertEquals("Ann. Sci. Univ. Jassy, Pt. 2, Sci. Nat.", nomRef.getInReference().getAbbrevTitle());
2034
        assertNull(nomRef.getEdition());
2035
        assertEquals("27", nomRef.getVolume());
2036

    
2037
        //same as Pt. 2, "Sect. xx" handled as series part but may change
2038
        parseStr = "Quercus boissieri var. microphylla (A. Camus) Zohary in Bull. Res. Council Israel, Sect. D, Bot. 9: 169. 1961";
2039
        name = parser.parseReferencedName(parseStr);
2040
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2041
        nomRef = name.getNomenclaturalReference();
2042
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2043
        assertEquals(ReferenceType.Article, nomRef.getType());
2044
        assertEquals("Bull. Res. Council Israel, Sect. D, Bot.", nomRef.getInReference().getAbbrevTitle());
2045
        assertNull(nomRef.getEdition());
2046
        assertEquals("9", nomRef.getVolume());
2047

    
2048
        //see above
2049
        parseStr = "Fimbristylis dichotoma var. annua (All.) T. Koyama in J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot. 8: 111. 1961";
2050
        name = parser.parseReferencedName(parseStr);
2051
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2052
        nomRef = name.getNomenclaturalReference();
2053
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2054
        assertEquals(ReferenceType.Article, nomRef.getType());
2055
        assertEquals("J. Fac. Sci. Univ. Tokyo, Sect. 3, Bot.", nomRef.getInReference().getAbbrevTitle());
2056
        assertNull(nomRef.getEdition());
2057
        assertEquals("8", nomRef.getVolume());
2058

    
2059

    
2060
        // "- "
2061
        parseStr = "Theresia tulipilfoia (M. Bieb.) Klatt in Hamburger Garten- Blumenzeitung 16: 438. 1860";
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("Hamburger Garten- Blumenzeitung", nomRef.getInReference().getAbbrevTitle());
2068
        assertNull(nomRef.getEdition());
2069
        assertEquals("16", nomRef.getVolume());
2070

    
2071
        parseStr = "Hyssopus officinalis var. pilifer Pant. in Verh. Vereins Natur- Heilk. Presburg, n.s., 2: 61. 1874";
2072
        name = parser.parseReferencedName(parseStr);
2073
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2074
        nomRef = name.getNomenclaturalReference();
2075
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2076
        assertEquals(ReferenceType.Article, nomRef.getType());
2077
        //, n.s., is not necessarily part of the title in future
2078
        assertEquals("Verh. Vereins Natur- Heilk. Presburg, n.s.,", nomRef.getInReference().getAbbrevTitle());
2079
        assertNull(nomRef.getEdition());
2080
        assertEquals("2", nomRef.getVolume());
2081

    
2082
          //Note: space in E+M, no space in IPNI; is it really a book?
2083
        parseStr = "Amaryllis dubia Houtt., Handl. Pl.- Kruidk. 12: 181. 1780";
2084
        name = parser.parseReferencedName(parseStr);
2085
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2086
        nomRef = name.getNomenclaturalReference();
2087
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2088
        assertEquals(ReferenceType.Book, nomRef.getType());
2089
        assertEquals("Handl. Pl.- Kruidk.", nomRef.getAbbrevTitle());
2090
        assertNull(nomRef.getEdition());
2091
        assertEquals("12", nomRef.getVolume());
2092

    
2093
        // "..."
2094
        parseStr = "Chamaesyce biramensis (Urb.) Alain in Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\" 11: 12. 1952";
2095
        name = parser.parseReferencedName(parseStr);
2096
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2097
        nomRef = name.getNomenclaturalReference();
2098
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2099
        assertEquals(ReferenceType.Article, nomRef.getType());
2100
        assertEquals("Contr. Ocas. Mus. Hist. Nat. Colegio \"De La Salle\"", nomRef.getInReference().getAbbrevTitle());
2101
        assertNull(nomRef.getEdition());
2102
        assertEquals("11", nomRef.getVolume());
2103

    
2104
        //' & '
2105
        parseStr = "Mannaphorus Raf. in Amer. Monthly Mag. & Crit. Rev. 1: 175. 1818";
2106
        name = parser.parseReferencedName(parseStr);
2107
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2108
        nomRef = name.getNomenclaturalReference();
2109
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2110
        assertEquals(ReferenceType.Article, nomRef.getType());
2111
        assertEquals("Amer. Monthly Mag. & Crit. Rev.", nomRef.getInReference().getAbbrevTitle());
2112
        assertNull(nomRef.getEdition());
2113
        assertEquals("1", nomRef.getVolume());
2114

    
2115
        //only for debugging
2116
        boolean  matches;
2117
        matches = "Flo & Amer. Fauna. Ab.".matches (NonViralNameParserImplRegExBase.referenceTitleFirstPart + "*");
2118
        Assert.assertTrue("referenceTitleFirstPart", matches);
2119

    
2120
        matches = "Fl. Amer. & Fauna. Ab. 101".matches (NonViralNameParserImplRegExBase.pSoftArticleReference);
2121
        Assert.assertTrue("pSoftArticleReference", matches);
2122
        //only for debugging end
2123

    
2124
        parseStr = "Corallorhiza trifida subsp. virescens (Drejer) L\u00F8jtnant in Fl. & Fauna (Esbjerg) 101: 71. 1996";
2125
        name = parser.parseReferencedName(parseStr);
2126
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2127
        nomRef = name.getNomenclaturalReference();
2128
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2129
        assertEquals(ReferenceType.Article, nomRef.getType());
2130
        assertEquals("Fl. & Fauna (Esbjerg)", nomRef.getInReference().getAbbrevTitle());
2131
        assertNull(nomRef.getEdition());
2132
        assertEquals("101", nomRef.getVolume());
2133

    
2134
        parseStr = "Crocus isauricus Siehe ex Bowles, Handb. Crocus & Colch.: 126. 1924";
2135
        name = parser.parseReferencedName(parseStr);
2136
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2137
        nomRef = name.getNomenclaturalReference();
2138
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2139
        assertEquals(ReferenceType.Book, nomRef.getType());
2140
        assertEquals("Handb. Crocus & Colch.", nomRef.getAbbrevTitle());
2141
        assertNull(nomRef.getEdition());
2142
        assertNull(nomRef.getVolume());
2143

    
2144
        parseStr = "Ornithogalum bifolium (L.) Neck. in Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat. 2: 461. 1770";
2145
        name = parser.parseReferencedName(parseStr);
2146
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2147
        nomRef = name.getNomenclaturalReference();
2148
        Assert.assertFalse("nom.ref. should be parsable", nomRef.isProtectedTitleCache());
2149
        assertEquals(ReferenceType.Article, nomRef.getType());
2150
        assertEquals("Hist. & Commentat. Acad. Elect. Sci. Theod.-Palat.", nomRef.getInReference().getAbbrevTitle());
2151
        assertNull(nomRef.getEdition());
2152
        assertEquals("2", nomRef.getVolume());
2153

    
2154
    }
2155

    
2156

    
2157
    @Test
2158
    public final void testSeriesPart(){
2159
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.pSeriesPart);
2160
        Matcher matcher = seriesPattern.matcher("ser. 2");
2161
        Assert.assertTrue("", matcher.matches());
2162

    
2163
        matcher = seriesPattern.matcher("n.s.");
2164
        Assert.assertTrue("", matcher.matches());
2165

    
2166
//        matcher = seriesPattern.matcher("a.s.");
2167
//        Assert.assertTrue("", matcher.matches());
2168

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

    
2173
        matcher = seriesPattern.matcher("Ser. C");
2174
        Assert.assertTrue("", matcher.matches());
2175

    
2176
        matcher = seriesPattern.matcher("S\u00E9r. B 1");
2177
        Assert.assertTrue("", matcher.matches());
2178

    
2179
        matcher = seriesPattern.matcher("Jerusalem Ser.");
2180
        Assert.assertTrue("", matcher.matches());
2181

    
2182
        matcher = seriesPattern.matcher("nov. Ser.");
2183
        Assert.assertTrue("", matcher.matches());
2184

    
2185

    
2186

    
2187
    }
2188

    
2189
    /**
2190
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#fullTeams(java.lang.String)}.
2191
     */
2192
    @Test
2193
    public final void testFullTeams() {
2194
        logger.warn("Not yet implemented"); // TODO
2195
    }
2196

    
2197
    /**
2198
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#AuthorshipAndEx(java.lang.String)}.
2199
     * @throws StringNotParsableException
2200
     */
2201
    @Test
2202
    public final void testParseAuthorsTaxonNameString() throws StringNotParsableException {
2203
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
2204
        parser.parseAuthors(nvn, "Eckweiler & ten Hagen, 2003");
2205
        Team team = (Team)nvn.getCombinationAuthorship();
2206
        Assert.assertNotNull("Comb. author must not be null", team);
2207
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
2208
        Assert.assertEquals("Second member must be 'ten Hagen'", "ten Hagen", team.getTeamMembers().get(1).getTitleCache());
2209

    
2210
        //Crosson du Cormier, 1964
2211
        IZoologicalName zooName = TaxonNameFactory.NewZoologicalInstance(null);
2212
        parser.parseAuthors(zooName, "Crosson du Cormier, 1964");
2213
        Person person = (Person)zooName.getCombinationAuthorship();
2214
        Assert.assertNotNull("Comb. author must not be null", person);
2215
        Assert.assertEquals("Persons title must be 'Crosson du Cormier'", "Crosson du Cormier", person.getTitleCache());
2216
        Assert.assertEquals("Year must be 1964", Integer.valueOf(1964), zooName.getPublicationYear() );
2217

    
2218
        //(van der Hoeven, 1839)
2219
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2220
        parser.parseAuthors(zooName, "(van der Hoeven, 1839)");
2221
        Assert.assertNull("Combination author must be null", zooName.getCombinationAuthorship());
2222
        person = (Person)zooName.getBasionymAuthorship();
2223
        Assert.assertNotNull("Basionym author must not be null", person);
2224
        Assert.assertEquals("Persons title must be 'van der Hoeven'", "van der Hoeven", person.getTitleCache());
2225
        Assert.assertEquals("Year must be 1839", Integer.valueOf(1839), zooName.getOriginalPublicationYear() );
2226

    
2227
        //le Doux, 1931
2228
        zooName = TaxonNameFactory.NewZoologicalInstance(null);
2229
        parser.parseAuthors(zooName, "le Doux, 1931");
2230
        person = (Person)zooName.getCombinationAuthorship();
2231
        Assert.assertNotNull("Comb. author must not be null", person);
2232
        Assert.assertEquals("Persons title must be 'le Doux'", "le Doux", person.getTitleCache());
2233
        Assert.assertEquals("Year must be 1931", Integer.valueOf(1931), zooName.getPublicationYear() );
2234

    
2235

    
2236
    }
2237

    
2238
    @Test  //#4764
2239
    public void testParseSection(){
2240
        //this test does not really test problematic cases where sect.idInVoc = "sect." instead of "sect.(bot.)"
2241
        //however, by changing the csv file entry to sect. just for testing it can be used as a functional test
2242
        String sectionNameStr = "Taraxacum sect. Testtaxa M\u00fcller, Incredible Taxa: 12. 2016";
2243
        INonViralName sectionName = parser.parseReferencedName(sectionNameStr, NomenclaturalCode.ICNAFP, null);
2244
        int parsingProblem = sectionName.getParsingProblem();
2245
        Assert.assertEquals("Problem should be 0", 0, parsingProblem);
2246
        Rank rank = sectionName.getRank();
2247
        Assert.assertEquals("", Rank.SECTION_BOTANY(), rank  );
2248
    }
2249

    
2250
    //#6577
2251
    @Test
2252
    public final void testParseSpNov(){
2253
        //Canabio, issue with space
2254
        INonViralName name = parser.parseFullName("Iresine sp. nov. 1");
2255
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2256
        Assert.assertEquals("sp. nov. 1", name.getSpecificEpithet());
2257

    
2258
        name = parser.parseFullName("Gomphichis sp. 22");
2259
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2260
        Assert.assertEquals("sp. 22", name.getSpecificEpithet());
2261

    
2262
        name = parser.parseFullName("Phleum sp. nov.");
2263
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2264
        Assert.assertEquals("sp. nov.", name.getSpecificEpithet());
2265

    
2266
        name = parser.parseFullName("Phleum sp.");
2267
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2268
        Assert.assertEquals("sp.", name.getSpecificEpithet());
2269

    
2270
    }
2271

    
2272

    
2273
    @Test  //#5072
2274
    public final void testLongRunningParsingCapitals(){
2275
        DateTime start = DateTime.now();
2276
        String nameStr = "Nazeris fujianensis JIAYAO HU, LIZHEN LI, MEIJUN ZHAO,2010";  //name from CoL that created problems
2277
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICZN, null);
2278
        DateTime end = DateTime.now();
2279
        Duration duration = new Duration(start, end);
2280
        long seconds = duration.getStandardSeconds();
2281
        //this is the critical part of the test that must not be changed
2282
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2283

    
2284
    }
2285

    
2286
    @Test  //#5072
2287
    //http://www.regular-expressions.info/catastrophic.html
2288
    public final void testLongRunningParsing(){
2289

    
2290
        //name only
2291
        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";
2292
        DateTime start = DateTime.now();
2293
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2294
        DateTime end = DateTime.now();
2295
        Duration duration = new Duration(start, end);
2296
        long seconds = duration.getStandardSeconds();
2297
        //this is the critical part of the test that must not be changed
2298
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2299
        //the following may be discussed
2300
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2301

    
2302

    
2303
        //with reference
2304
        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.";
2305
        start = DateTime.now();
2306
        name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2307
        end = DateTime.now();
2308
        duration = new Duration(start, end);
2309
        seconds = duration.getStandardSeconds();
2310
        //this is the critical part of the test that must not be changed
2311
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2312
        //the following may be discussed
2313
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2314
    }
2315

    
2316
    @Test  //#5072
2317
    public final void testLongRunningParsingAuthors(){
2318
        //http://www.regular-expressions.info/catastrophic.html
2319
        //
2320
        //Länge des Nachnamens macht keinen Unterschied
2321
        //Anzahl der "AuthorParts scheint entscheidend
2322
        // & am Ende macht es langsamger (16s), als nur ","(6s))
2323

    
2324
        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";
2325
        TeamOrPersonBase[] authorArray = new TeamOrPersonBase[4];
2326
        try {
2327
            DateTime start = DateTime.now();
2328
            parser.fullAuthors(authorStr, authorArray, new Integer[]{1800, null, null, null}, NomenclaturalCode.ICNAFP);
2329
            DateTime end = DateTime.now();
2330
            Duration duration = new Duration(start, end);
2331
            long seconds = duration.getStandardSeconds();
2332
//            System.out.println(seconds);
2333
            //this is the critical part of the test that must not be changed
2334
            Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2335
        } catch (StringNotParsableException e) {
2336
            e.printStackTrace();
2337
            Assert.fail("Authors should be parsable");
2338
        }
2339

    
2340
    }
2341

    
2342

    
2343
    /**
2344
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#AuthorshipAndEx(java.lang.String)}.
2345
     */
2346
    @Test
2347
    public final void testAuthorshipAndEx() {
2348
        logger.warn("Not yet implemented"); // TODO
2349
    }
2350

    
2351
    /**
2352
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#Authorship(java.lang.String)}.
2353
     */
2354
    @Test
2355
    public final void testAuthorship() {
2356
        logger.warn("Not yet implemented"); // TODO
2357
    }
2358

    
2359
    /**
2360
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseCultivar(java.lang.String)}.
2361
     */
2362
    @Test
2363
    public final void testParseCultivar() {
2364
        logger.warn("Not yet implemented"); // TODO
2365
    }
2366

    
2367
    @Test
2368
    public final void testNomenclaturalStatus() {
2369
        IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY(), "Acanthopale", null, null, null, null, null, null, null);
2370
        name.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ALTERNATIVE()));
2371
        IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
2372
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2373
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2374
        Assert.assertEquals("Title cache should be same. No duplication of nom. status should take place", name.getFullTitleCache(), name2.getFullTitleCache());
2375
    }
2376

    
2377
    @Test
2378
    public final void testSpecificAuthors(){
2379
        //McVaugh
2380
        INonViralName name = parser.parseFullName("Psidium longipes var. orbiculare (O.Berg) McVaugh");
2381
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2382
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2383
        assertEquals( "McVaugh", combinationAuthor.getNomenclaturalTitle());
2384
        TeamOrPersonBase<?> basionymAuthor = name.getBasionymAuthorship();
2385
        assertEquals( "O.Berg", basionymAuthor.getNomenclaturalTitle());
2386

    
2387
//      Campanula rhodensis A. DC.
2388

    
2389
    }
2390

    
2391
    @Test
2392
    public final void testBookSectionAuthors(){
2393
        INonViralName name;
2394
        Reference nomRef;
2395
        String title;
2396
        String str;
2397

    
2398
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2399
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2400
        name = parser.parseReferencedName(str);
2401
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2402
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2403
        assertEquals( "Asch. & Schweinf.", combinationAuthor.getNomenclaturalTitle());
2404
        nomRef = name.getNomenclaturalReference();
2405
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2406
        assertEquals( "Barbey-Boissier & Barbey", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2407
        title = nomRef.getInReference().getAbbrevTitle();
2408
        assertEquals( "Herb. Levant", title);
2409

    
2410
        name = parser.parseReferencedName("Luzula multiflora subsp. pallescens (Sw.) Reichg. in Van Ooststroom & al., Fl. Neerl. 1: 208. 1964");
2411
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2412
        assertEquals( "Reichg.", name.getCombinationAuthorship().getNomenclaturalTitle());
2413
        nomRef = name.getNomenclaturalReference();
2414
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2415
        assertEquals( "Van Ooststroom & al.", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2416
        title = nomRef.getInReference().getAbbrevTitle();
2417
        assertEquals( "Fl. Neerl.", title);
2418

    
2419
        str = "Salvia pratensis var. albiflora T. Durand in De Wildeman & Durand, Prodr. Fl. Belg. 3: 663. 1899";
2420
        name = parser.parseReferencedName(str);
2421
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2422
        assertEquals( "T. Durand", name.getCombinationAuthorship().getNomenclaturalTitle());
2423
        nomRef = name.getNomenclaturalReference();
2424
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2425
        assertEquals( "De Wildeman & Durand", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2426
        title = nomRef.getInReference().getAbbrevTitle();
2427
        assertEquals( "Prodr. Fl. Belg.", title);
2428

    
2429
        str = "Bravoa Lex. in La Llave & Lexarza, Nov. Veg. Desc. 1: 6. 1824";
2430
        name = parser.parseReferencedName(str);
2431
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2432
        assertEquals( "Lex.", name.getCombinationAuthorship().getNomenclaturalTitle());
2433
        nomRef = name.getNomenclaturalReference();
2434
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2435
        assertEquals( "La Llave & Lexarza", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2436
        title = nomRef.getInReference().getAbbrevTitle();
2437
        assertEquals( "Nov. Veg. Desc.", title);
2438

    
2439
        str = "Thymus trachselianus var. vallicola Heinr. Braun in Dalla Torre & Sarnthein, Fl. Tirol 6(3): 204. 1912";
2440
        name = parser.parseReferencedName(str);
2441
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2442
        nomRef = name.getNomenclaturalReference();
2443
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2444
        assertEquals( "Dalla Torre & Sarnthein", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2445
        title = nomRef.getInReference().getAbbrevTitle();
2446
        assertEquals( "Fl. Tirol", title);
2447

    
2448
        //see #openIssues
2449
//        str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2450
//        name = parser.parseReferencedName(str);
2451
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2452
//        nomRef = name.getNomenclaturalReference();
2453
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2454
//        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2455
//        title = nomRef.getInReference().getAbbrevTitle();
2456
//        assertEquals( "Nova Fl. Portugal", title);
2457
//
2458
//        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2459
//        name = parser.parseReferencedName(str);
2460
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2461
//        nomRef = name.getNomenclaturalReference();
2462
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2463
//        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2464
//        title = nomRef.getInReference().getAbbrevTitle();
2465
//        assertEquals( "Mount. Fl. Greece", title);
2466

    
2467
    }
2468

    
2469
    @Test
2470
    public final void testDatePublished(){
2471

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

    
2478
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. 4 Apr 1977");
2479
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2480
        nomRef = name.getNomenclaturalReference();
2481
        assertEquals(ReferenceType.Article, nomRef.getType());
2482
        assertEquals("4 Apr 1977", nomRef.getDatePublished().toString());
2483
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getStartMonth());
2484

    
2485
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. Feb-Apr 1977");
2486
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2487
        nomRef = name.getNomenclaturalReference();
2488
        assertEquals(ReferenceType.Article, nomRef.getType());
2489
        assertEquals("Feb"+SEP+"Apr 1977", nomRef.getDatePublished().toString());
2490
        assertEquals(Integer.valueOf(2), nomRef.getDatePublished().getStartMonth());
2491
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getEndMonth());
2492
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getStartYear());
2493
        assertEquals(Integer.valueOf(1977), nomRef.getDatePublished().getEndYear());
2494
        assertNull(nomRef.getDatePublished().getStartDay());
2495
        assertNull(nomRef.getDatePublished().getEndDay());
2496
    }
2497

    
2498

    
2499
    @Test
2500
    public final void testExistingProblems(){
2501
        //Canabio, issue with space
2502
        INonViralName name = parser.parseReferencedName("Machaonia erythrocarpa var. hondurensis (Standl.) Borhidi"
2503
                + " in Acta Bot. Hung. 46 (1-2): 30. 2004");
2504
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2505
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2506
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2507
        Reference nomRef = name.getNomenclaturalReference();
2508
        assertEquals(ReferenceType.Article, nomRef.getType());
2509
        assertEquals("46 (1-2)", nomRef.getVolume());
2510

    
2511
        //Canabio, detail with fig.
2512
        name = parser.parseReferencedName("Didymaea floribunda Rzed."
2513
                + " in Bol. Soc. Bot. Mex. 44: 72, fig. 1. 1983");
2514
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2515
        combinationAuthor = name.getCombinationAuthorship();
2516
        assertEquals( "Rzed.", combinationAuthor.getNomenclaturalTitle());
2517
        nomRef = name.getNomenclaturalReference();
2518
        assertEquals(ReferenceType.Article, nomRef.getType());
2519
        assertEquals("44", nomRef.getVolume());
2520
        assertEquals("72, fig. 1", name.getNomenclaturalMicroReference());
2521

    
2522
        //fig with a-c and without dot
2523
        name = parser.parseReferencedName("Deppea guerrerensis Dwyer & Lorence"
2524
                + " in Allertonia 4: 428. fig 4a-c. 1988");  //
2525
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2526
        combinationAuthor = name.getCombinationAuthorship();
2527
        assertEquals( "Dwyer & Lorence", combinationAuthor.getNomenclaturalTitle());
2528
        nomRef = name.getNomenclaturalReference();
2529
        assertEquals(ReferenceType.Article, nomRef.getType());
2530
        assertEquals("4", nomRef.getVolume());
2531
        assertEquals("428. fig 4a-c", name.getNomenclaturalMicroReference());
2532

    
2533
        //issue with EN_DASH (3–4)
2534
        name = parser.parseReferencedName("Arachnothryx tacanensis (Lundell) Borhidi"
2535
              + " in Acta Bot. Hung. 33 (3" + UTF8.EN_DASH + "4): 303. 1987");
2536
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2537
        combinationAuthor = name.getCombinationAuthorship();
2538
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2539
        nomRef = name.getNomenclaturalReference();
2540
        assertEquals(ReferenceType.Article, nomRef.getType());
2541
        assertEquals("33 (3" + UTF8.EN_DASH + "4)", nomRef.getVolume());
2542
        assertEquals("303", name.getNomenclaturalMicroReference());
2543

    
2544
        //fig with f.
2545
        name = parser.parseReferencedName("Stenotis Terrell"
2546
                + " in Sida 19(4): 901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2. 2001");
2547
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2548
        combinationAuthor = name.getCombinationAuthorship();
2549
        assertEquals( "Terrell", combinationAuthor.getNomenclaturalTitle());
2550
        nomRef = name.getNomenclaturalReference();
2551
        assertEquals(ReferenceType.Article, nomRef.getType());
2552
        assertEquals("19(4)", nomRef.getVolume());
2553
        assertEquals("901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2", name.getNomenclaturalMicroReference());
2554

    
2555
        //detail with figs
2556
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2557
                + " in Contr. Dudley Herb. 3: 75, figs 4-6. 1940");
2558
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2559
        combinationAuthor = name.getCombinationAuthorship();
2560
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitle());
2561
        nomRef = name.getNomenclaturalReference();
2562
        assertEquals(ReferenceType.Article, nomRef.getType());
2563
        assertEquals("3", nomRef.getVolume());
2564
        assertEquals("75, figs 4-6", name.getNomenclaturalMicroReference());
2565

    
2566
        //detail with pl. and figs
2567
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2568
                + " in Contr. Dudley Herb. 3: 75, pl. 19, figs 4-6. 1940");
2569
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2570
        combinationAuthor = name.getCombinationAuthorship();
2571
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitle());
2572
        nomRef = name.getNomenclaturalReference();
2573
        assertEquals(ReferenceType.Article, nomRef.getType());
2574
        assertEquals("3", nomRef.getVolume());
2575
        assertEquals("75, pl. 19, figs 4-6", name.getNomenclaturalMicroReference());
2576

    
2577
        //pl
2578
        name = parser.parseReferencedName("Carapichea  Aubl."
2579
                + " in Hist. Pl. Guiane 1: 167, pl. 64. 1775");
2580
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2581
        combinationAuthor = name.getCombinationAuthorship();
2582
        assertEquals( "Aubl.", combinationAuthor.getNomenclaturalTitle());
2583
        nomRef = name.getNomenclaturalReference();
2584
        assertEquals(ReferenceType.Article, nomRef.getType());
2585
        assertEquals("1", nomRef.getVolume());
2586
        assertEquals("167, pl. 64", name.getNomenclaturalMicroReference());
2587

    
2588
        //fig with ,
2589
        name = parser.parseReferencedName("Hoffmannia ixtlanensis Lorence"
2590
                + " in Novon 4: 121. fig. 2a, b. 1994");
2591
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2592
        combinationAuthor = name.getCombinationAuthorship();
2593
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitle());
2594
        nomRef = name.getNomenclaturalReference();
2595
        assertEquals(ReferenceType.Article, nomRef.getType());
2596
        assertEquals("4", nomRef.getVolume());
2597
        assertEquals("121. fig. 2a, b", name.getNomenclaturalMicroReference());
2598

    
2599
        //detail with , to number
2600
        name = parser.parseReferencedName("Deppea martinez-calderonii Lorence"
2601
                + " in Allertonia 4: 399. figs 1e, 2. 1988");
2602
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2603
        combinationAuthor = name.getCombinationAuthorship();
2604
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitle());
2605
        nomRef = name.getNomenclaturalReference();
2606
        assertEquals(ReferenceType.Article, nomRef.getType());
2607
        assertEquals("4", nomRef.getVolume());
2608
        assertEquals("399. figs 1e, 2", name.getNomenclaturalMicroReference());
2609

    
2610
        //(Suppl.)
2611
        name = parser.parseReferencedName("Manettia costaricensis  Wernham"
2612
                + " in J. Bot. 57(Suppl.): 38. 1919");
2613
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2614
        combinationAuthor = name.getCombinationAuthorship();
2615
        assertEquals( "Wernham", combinationAuthor.getNomenclaturalTitle());
2616
        nomRef = name.getNomenclaturalReference();
2617
        assertEquals(ReferenceType.Article, nomRef.getType());
2618
        assertEquals("57(Suppl.)", nomRef.getVolume());
2619
        assertEquals("38", name.getNomenclaturalMicroReference());
2620

    
2621
        //NY.
2622
        name = parser.parseReferencedName("Crusea psyllioides (Kunth) W.R. Anderson"
2623
                + " in Mem. NY. Bot. Gard. 22: 75. 1972");
2624
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2625
        combinationAuthor = name.getCombinationAuthorship();
2626
        assertEquals( "W.R. Anderson", combinationAuthor.getNomenclaturalTitle());
2627
        nomRef = name.getNomenclaturalReference();
2628
        assertEquals(ReferenceType.Article, nomRef.getType());
2629
        assertEquals("22", nomRef.getVolume());
2630
        assertEquals("75", name.getNomenclaturalMicroReference());
2631

    
2632
        //apostroph word in title
2633
        name = parser.parseReferencedName("Sabicea glabrescens Benth."
2634
                + " in Hooker's J. Bot. Kew Gard. Misc. 3: 219. 1841");
2635
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2636
        combinationAuthor = name.getCombinationAuthorship();
2637
        assertEquals( "Benth.", combinationAuthor.getNomenclaturalTitle());
2638
        nomRef = name.getNomenclaturalReference();
2639
        assertEquals(ReferenceType.Article, nomRef.getType());
2640
        assertEquals("3", nomRef.getVolume());
2641
        assertEquals("219", name.getNomenclaturalMicroReference());
2642

    
2643
        // place published e.g. (Hannover)
2644
        name = parser.parseReferencedName("Pittoniotis trichantha Griseb."
2645
                  + " in Bonplandia (Hannover) 6 (1): 8. 1858");
2646
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2647
        combinationAuthor = name.getCombinationAuthorship();
2648
        assertEquals( "Griseb.", combinationAuthor.getNomenclaturalTitle());
2649
        nomRef = name.getNomenclaturalReference();
2650
        assertEquals(ReferenceType.Article, nomRef.getType());
2651
        assertEquals("6 (1)", nomRef.getVolume());
2652
        assertEquals("8", name.getNomenclaturalMicroReference());
2653

    
2654
        //komplex / incorrect year without quotation marks
2655
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2656
                + " in Acta Bot. Hung. 29(1\u20134): 16, f. 1\u20132, t. 1-8. 1983 [1984]");
2657
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2658
        combinationAuthor = name.getCombinationAuthorship();
2659
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2660
        nomRef = name.getNomenclaturalReference();
2661
        assertEquals(ReferenceType.Article, nomRef.getType());
2662
        assertEquals("29(1\u20134)", nomRef.getVolume());
2663
        assertEquals("16, f. 1\u20132, t. 1-8", name.getNomenclaturalMicroReference());
2664
        assertEquals("1983 [1984]", nomRef.getDatePublishedString());
2665
//        assertEquals("1984", nomRef.getYear()); //was like this, but is not necessarily correct, see #7429
2666

    
2667
        //incorrect year with \u201e \u201f  (s. eu.etaxonomy.cdm.common.UTF8.ENGLISH_QUOT_START
2668
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2669
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \u201e1983\u201f [1984]");
2670
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2671
        combinationAuthor = name.getCombinationAuthorship();
2672
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2673
        nomRef = name.getNomenclaturalReference();
2674
        assertEquals(ReferenceType.Article, nomRef.getType());
2675
        assertEquals("29(1-4)", nomRef.getVolume());
2676
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2677
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2678
        assertEquals("1984", nomRef.getYear());
2679

    
2680
        //incorrect year with "
2681
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2682
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \"1983\" [1984]");
2683
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2684
        combinationAuthor = name.getCombinationAuthorship();
2685
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2686
        nomRef = name.getNomenclaturalReference();
2687
        assertEquals(ReferenceType.Article, nomRef.getType());
2688
        assertEquals("29(1-4)", nomRef.getVolume());
2689
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2690
        //changed from "1983" [1984] to 1984 ["1983"] after implementing #7429
2691
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2692
        assertEquals("1984", nomRef.getYear());
2693

    
2694
        //fig. a
2695
        name = parser.parseReferencedName("Psychotria capitata  Ruiz & Pav."
2696
                + " in Fl. Peruv. 2: 59, pl. 206, fig. a. 1799");
2697
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2698
        combinationAuthor = name.getCombinationAuthorship();
2699
        assertEquals( "Ruiz & Pav.", combinationAuthor.getNomenclaturalTitle());
2700
        nomRef = name.getNomenclaturalReference();
2701
        assertEquals(ReferenceType.Article, nomRef.getType());
2702
        assertEquals("2", nomRef.getVolume());
2703
        assertEquals("59, pl. 206, fig. a", name.getNomenclaturalMicroReference());
2704

    
2705
        //442A.
2706
        name = parser.parseReferencedName("Rogiera elegans Planch."
2707
                + " in Fl. Serres Jard. Eur. 5: 442A. 1849");
2708
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2709
        combinationAuthor = name.getCombinationAuthorship();
2710
        assertEquals( "Planch.", combinationAuthor.getNomenclaturalTitle());
2711
        nomRef = name.getNomenclaturalReference();
2712
        assertEquals(ReferenceType.Article, nomRef.getType());
2713
        assertEquals("5", nomRef.getVolume());
2714
        assertEquals("442A", name.getNomenclaturalMicroReference());
2715

    
2716
        //f
2717
        name = parser.parseReferencedName("Coussarea imitans L.O. Williams"
2718
                + " in Phytologia 26 (6): 488-489, f. 1973");
2719
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2720
        combinationAuthor = name.getCombinationAuthorship();
2721
        assertEquals( "L.O. Williams", combinationAuthor.getNomenclaturalTitle());
2722
        nomRef = name.getNomenclaturalReference();
2723
        assertEquals(ReferenceType.Article, nomRef.getType());
2724
        assertEquals("26 (6)", nomRef.getVolume());
2725
        assertEquals("488-489, f", name.getNomenclaturalMicroReference());
2726

    
2727
        //Phys.-Med.
2728
        name = parser.parseReferencedName("Coccocypselum cordifolium Nees & Mart."
2729
                + " in Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur. 12: 14. 1824");
2730
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2731
        combinationAuthor = name.getCombinationAuthorship();
2732
        assertEquals( "Nees & Mart.", combinationAuthor.getNomenclaturalTitle());
2733
        nomRef = name.getNomenclaturalReference();
2734
        assertEquals(ReferenceType.Article, nomRef.getType());
2735
        assertEquals("Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur.", nomRef.getInReference().getAbbrevTitle());
2736
        assertEquals("12", nomRef.getVolume());
2737
        assertEquals("14", name.getNomenclaturalMicroReference());
2738
        assertEquals("1824", nomRef.getYear());
2739

    
2740
        //(ed. 10)  wanted?
2741
//        Syst. Nat. (ed. 10) 2: 930. 1759
2742
//        name = parser.parseReferencedName("Erithalis fruticosa L."
2743
//                + ", Syst. Nat. ed. 10, 2: 930. 1759");
2744
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2745
//        combinationAuthor = name.getCombinationAuthorship();
2746
//        assertEquals( "L.", combinationAuthor.getNomenclaturalTitle());
2747
//        nomRef = (Reference)name.getNomenclaturalReference();
2748
//        assertEquals(ReferenceType.Book, nomRef.getType());
2749
//        assertEquals("2", nomRef.getVolume());
2750
//        assertEquals("10", nomRef.getEdition());
2751
//        assertEquals("930", name.getNomenclaturalMicroReference());
2752
//        assertEquals("1759", nomRef.getYear());
2753

    
2754
        //issue with letter "(1a)"
2755
        name = parser.parseReferencedName("Arthraerua (Kuntze) Schinz,"
2756
                + " Nat. Pflanzenfam. 3(1a): 109. 1893");
2757
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2758
        combinationAuthor = name.getCombinationAuthorship();
2759
        assertEquals( "Schinz", combinationAuthor.getNomenclaturalTitle());
2760
        nomRef = name.getNomenclaturalReference();
2761
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
2762
        assertEquals(ReferenceType.Book, nomRef.getType());
2763
        assertEquals("Nat. Pflanzenfam.", nomRef.getAbbrevTitle());
2764
        assertEquals("3(1a)", nomRef.getVolume());
2765
        assertEquals("109", name.getNomenclaturalMicroReference());
2766
        assertEquals("1893", nomRef.getYear());
2767

    
2768
        //Accent graph in author name #6057
2769
        name = parser.parseReferencedName("Sedum plicatum O`Brian");
2770
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2771
        assertEquals( "O`Brian", name.getCombinationAuthorship().getNomenclaturalTitle());
2772

    
2773
        //-e-  #6060
2774
        name = parser.parseReferencedName("Thamniopsis stenodictyon (Sehnem) Oliveira-e-Silva & O.Yano");
2775
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2776
        Team team = (Team)name.getCombinationAuthorship();
2777
        assertEquals( "Oliveira-e-Silva", team.getTeamMembers().get(0).getNomenclaturalTitle());
2778

    
2779
        //Vorabdr.
2780
        name = parser.parseReferencedName("Ophrys hystera  Kreutz & Ruedi Peter in J. Eur. Orchideen 30(Vorabdr.): 128. 1997");
2781
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2782
        assertEquals( "30(Vorabdr.)", name.getNomenclaturalReference().getVolume());
2783

    
2784
        //#6100  jun.
2785
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2786
        name = parser.parseFullName(nameStr, botanicCode, null);  //fails with missing botanicCode, see open issues
2787
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2788
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2789

    
2790
        //#6100 bis /ter
2791
        nameStr = "Schistidium aquaticum (R.Br.ter) Ochyra";
2792
        name = parser.parseFullName(nameStr);
2793
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2794
        assertEquals( "R.Br.ter", name.getBasionymAuthorship().getTitleCache());
2795

    
2796
        nameStr = "Grimmia mitchellii R.Br.bis";
2797
        name = parser.parseFullName(nameStr);
2798
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2799
        assertEquals( "R.Br.bis", name.getCombinationAuthorship().getTitleCache());
2800

    
2801
        //forma #6100
2802
        nameStr = "Xerocomus parasiticus forma piperatoides (J. Blum) R. Mazza";
2803
        name = parser.parseFullName(nameStr);
2804
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2805
        assertEquals( "piperatoides", name.getInfraSpecificEpithet());
2806
        assertEquals( Rank.FORM(), name.getRank());
2807

    
2808
        //subgen. #6100
2809
        nameStr = "Aliciella subgen. Gilmania (H.Mason & A.D.Grant) J.M.Porter";
2810
        name = parser.parseFullName(nameStr);
2811
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2812
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2813
        assertEquals( Rank.SUBGENUS(), name.getRank());
2814

    
2815
        //subgen. #6100
2816
        nameStr = "Aliciella subgen. Gilmania J.M.Porter";
2817
        name = parser.parseFullName(nameStr);
2818
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2819
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2820
        assertEquals( Rank.SUBGENUS(), name.getRank());
2821
        assertEquals( "J.M.Porter", name.getCombinationAuthorship().getTitleCache());
2822

    
2823
        //la Croix #6100
2824
        nameStr = "Eulophia ovalis var. bainesii (Rolfe) P.J.Cribb & la Croix";
2825
        name = parser.parseFullName(nameStr);
2826
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2827
        assertEquals( "P.J.Cribb & la Croix", name.getCombinationAuthorship().getTitleCache());
2828

    
2829
        //I = Yi #6100
2830
        nameStr = "Parasenecio hwangshanicus (P.I Mao) C.I Peng";
2831
        name = parser.parseFullName(nameStr);
2832
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2833
        assertEquals("I (=Yi) should be an accepted ending", "C.I Peng", name.getCombinationAuthorship().getTitleCache());
2834
        assertEquals("I (=Yi) should be an accepted ending", "P.I Mao", name.getBasionymAuthorship().getTitleCache());
2835

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

    
2843
        //Man in 't Veld  #6100
2844
        nameStr = "Phytophthora multivesiculata Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters";
2845
        name = parser.parseFullName(nameStr);
2846
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2847
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & al.",
2848
                name.getCombinationAuthorship().getTitleCache());
2849
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
2850
                name.getCombinationAuthorship().getNomenclaturalTitle());
2851

    
2852
        nameStr = "Thymus \u00D7 herberoi De la Torre, Vicedo, Alonso & Paya";
2853
        name = parser.parseFullName(nameStr);
2854
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2855
        assertEquals("De la Torre, Vicedo, Alonso & al.",
2856
                name.getCombinationAuthorship().getTitleCache());
2857
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
2858
                name.getCombinationAuthorship().getNomenclaturalTitle());
2859

    
2860
        //Sant'Anna
2861
        nameStr = "Coelosphaerium evidenter-marginatum M.T.P.Azevedo & Sant'Anna";
2862
        name = parser.parseFullName(nameStr);
2863
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2864
        assertEquals("M.T.P.Azevedo & Sant'Anna", name.getCombinationAuthorship().getTitleCache());
2865

    
2866
        //Heft
2867
        nameStr = "Nepenthes deaniana Macfarl. in Engl., Mein Pflanzenr. IV. 111 (Heft 36): 57. 1908.";
2868
        name = parser.parseReferencedName(nameStr);
2869
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2870
        Reference ref = name.getNomenclaturalReference();
2871
        Assert.assertFalse("Reference should be parsable", ref.hasProblem());
2872
        //or even better IV. 111 (Heft 36), but this is currently not implemented
2873
        assertEquals("111 (Heft 36)", ref.getInReference().getVolume());
2874

    
2875
        //journal with commata at pos 4
2876
        nameStr = "Bufonia kotschyana subsp. densa Chrtek & Krisa in Acta Univ.Carol., Biol. 43(2): 105. 1999";
2877
        name = parser.parseReferencedName(nameStr);
2878
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2879
        String author = name.getAuthorshipCache();
2880
        assertEquals("Chrtek & Krisa", author);
2881
        ref = name.getNomenclaturalReference();
2882
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2883
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2884

    
2885
    }
2886

    
2887
    @Test
2888
    @Ignore
2889
    public final void openIssues(){
2890
        //#6100  jun.
2891
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2892
        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
2893
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2894
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2895
        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
2896
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2897
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2898

    
2899
        //´t Hart #6100
2900
        nameStr = "Sedum decipiens (Baker) Thiede & \u00B4t Hart";   //still does not work with "´" if compiled by maven, don't know what the difference is
2901
        name = parser.parseFullName(nameStr);
2902
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2903
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2904
                "Thiede & \u00B4t Hart", name.getCombinationAuthorship().getTitleCache());
2905
        nameStr = "Sedum decipiens (Baker) Thiede & ´t Hart";   //does not work if compiled with maven
2906
        name = parser.parseFullName(nameStr);
2907
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2908
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2909
                "Thiede & ´t Hart", name.getCombinationAuthorship().getTitleCache());
2910

    
2911
        //should be recognized as book section (see testBookSectionAuthors)
2912
        String str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2913
        name = parser.parseReferencedName(str);
2914
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2915
        Reference nomRef = name.getNomenclaturalReference();
2916
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2917
        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2918
        assertEquals( "Nova Fl. Portugal", nomRef.getInReference().getAbbrevTitle());
2919

    
2920
        //same
2921
        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2922
        name = parser.parseReferencedName(str);
2923
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2924
        nomRef = name.getNomenclaturalReference();
2925
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2926
        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2927
        assertEquals( "Mount. Fl. Greece", nomRef.getInReference().getAbbrevTitle());
2928
    }
2929

    
2930
}
(2-2/4)