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
    /**
485
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
486
     */
487
    @Test
488
    public final void testHybrids() {
489
        INonViralName name1;
490

    
491

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

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

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

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

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

    
528
        //Subspecies hybrid with notho / n
529
        name1 = parser.parseFullName("Aegilops insulae nothosubsp. abies Scholz", botanicCode, null);
530
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
531
        assertFalse("Name must not have binom hybrid bit set", name1.isBinomHybrid());
532
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
533
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
534
        assertEquals("Infraspecific epithet must be 'abies'", "abies", name1.getInfraSpecificEpithet());
535

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

    
543
        //
544
        String nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
545
        name1 = parser.parseFullName(nameStr);
546
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
547
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
548
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
549
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
550
        assertEquals(nameStr, name1.getTitleCache());  //we expect the cache strategy to create the same result
551

    
552
        nameStr = "Dactylorhiza \u00D7incarnata nothosubsp. versicolor";
553
        name1 = parser.parseFullName(nameStr);
554
        assertFalse("Name must not have monom hybrid bit set", name1.isMonomHybrid());
555
        assertTrue("Name must have binom hybrid bit set", name1.isBinomHybrid());
556
        assertTrue("Name must have trinom hybrid bit set", name1.isTrinomHybrid());
557
        assertFalse("Name must not be protected", name1.isProtectedTitleCache());
558
        assertEquals(nameStr, name1.getTitleCache());  //we expect the cache strategy to create the same result
559

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

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

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

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

    
591
    }
592

    
593
    /**
594
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
595
     */
596
    @Test
597
    public final void testUnrankedNames() {
598
        try {
599
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
600
            testName_StringNomcodeRank(parseMethod);
601
        } catch (Exception e) {
602
            e.printStackTrace();
603
            assertTrue(false);
604
        }
605

    
606
        //unranked infraspecific
607
        String infraspecificUnranked = "Genus species [unranked] infraspecific";
608
        INonViralName name = parser.parseFullName(infraspecificUnranked);
609
        assertEquals( "Genus", name.getGenusOrUninomial());
610
        assertEquals( "species", name.getSpecificEpithet());
611
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
612
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
613

    
614
        //'ranglos' infraspecific
615
        infraspecificUnranked = "Genus species [ranglos] infraspecific";
616
        name = parser.parseFullName(infraspecificUnranked);
617
        assertEquals( "Genus", name.getGenusOrUninomial());
618
        assertEquals( "species", name.getSpecificEpithet());
619
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
620
        assertEquals( "Unranked rank should be parsed", Rank.INFRASPECIFICTAXON(), name.getRank());
621

    
622
        //unranked infrageneric
623
        String infraGenericUnranked = "Genus [unranked] Infragen";
624
        INonViralName name2 = parser.parseFullName(infraGenericUnranked);
625
        assertEquals( "Genus", name2.getGenusOrUninomial());
626
        assertEquals( null, name2.getSpecificEpithet());
627
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
628
        assertEquals( "Unranked rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
629

    
630
        //unranked infrageneric
631
        infraGenericUnranked = "Genus [ranglos] Infragen";
632
         name2 = parser.parseFullName(infraGenericUnranked);
633
        assertEquals( "Genus", name2.getGenusOrUninomial());
634
        assertEquals( null, name2.getSpecificEpithet());
635
        assertEquals( "Infragen", name2.getInfraGenericEpithet());
636
        assertEquals( "Ranglos rank should be parsed", Rank.INFRAGENERICTAXON(), name2.getRank());
637

    
638
    }
639

    
640
    /**
641
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
642
     */
643
    @Test
644
    public final void testOldRanks() {
645
        try {
646
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
647
            testName_StringNomcodeRank(parseMethod);
648
        } catch (Exception e) {
649
            e.printStackTrace();
650
            assertTrue(false);
651
        }
652

    
653
        //proles
654
        String infraspecificUnranked = "Genus species proles infraspecific";
655
        INonViralName name = parser.parseFullName(infraspecificUnranked);
656
        assertEquals( "Genus", name.getGenusOrUninomial());
657
        assertEquals( "species", name.getSpecificEpithet());
658
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
659
        assertEquals( "Proles should be parsed", Rank.PROLES(), name.getRank());
660

    
661
        //sublusus
662
        infraspecificUnranked = "Genus species sublusus infraspecific";
663
        name = parser.parseFullName(infraspecificUnranked);
664
        assertEquals( "Genus", name.getGenusOrUninomial());
665
        assertEquals( "species", name.getSpecificEpithet());
666
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
667
        assertEquals( "Sublusus should be parsed", Rank.SUBLUSUS(), name.getRank());
668

    
669

    
670
        //race
671
        infraspecificUnranked = "Genus species race infraspecific";
672
        name = parser.parseFullName(infraspecificUnranked);
673
        assertEquals( "Genus", name.getGenusOrUninomial());
674
        assertEquals( "species", name.getSpecificEpithet());
675
        assertEquals( "infraspecific", name.getInfraSpecificEpithet());
676
        assertEquals( "Race should be parsed", Rank.RACE(), name.getRank());
677

    
678

    
679

    
680
    }
681

    
682

    
683
    /**
684
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseFullName(java.lang.String, eu.etaxonomy.cdm.model.name.Rank)}.
685
     */
686
    @Test
687
    public final void testHybridFormulars() {
688
        try {
689
            Method parseMethod = parser.getClass().getDeclaredMethod("parseFullName", String.class, NomenclaturalCode.class, Rank.class);
690
            testName_StringNomcodeRank(parseMethod);
691
        } catch (Exception e) {
692
            e.printStackTrace();
693
            assertTrue(false);
694
        }
695

    
696
        //Species hybrid
697
        String hybridCache = "Abies alba "+UTF8.HYBRID+" Pinus bus";
698
        INonViralName name1 = parser.parseFullName(hybridCache, botanicCode, null);
699
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
700
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
701
        assertEquals("Title cache must be correct", hybridCache, name1.getTitleCache());
702
        List<HybridRelationship> orderedRels = name1.getOrderedChildRelationships();
703
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
704
        TaxonName firstParent = orderedRels.get(0).getParentName();
705
        assertEquals("Name must have Abies alba as first hybrid parent", "Abies alba", firstParent.getTitleCache());
706
        TaxonName secondParent = orderedRels.get(1).getParentName();
707
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
708
        assertEquals("Hybrid name must have the lowest rank ('species') as rank", Rank.SPECIES(), name1.getRank());
709
        assertNull("Name must not have a genus eptithet", name1.getGenusOrUninomial());
710
        assertNull("Name must not have a specific eptithet", name1.getSpecificEpithet());
711
        assertFalse("Name must not have parsing problems", name1.hasProblem());
712

    
713
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
714
        assertFalse("Name must not have parsing problems", name1.hasProblem());
715

    
716
        //x-sign
717
        hybridCache = "Abies alba x Pinus bus";
718
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
719
        assertFalse("Name must be parsable", name1.hasProblem());
720
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
721
        assertFalse("Name must not have parsing problems", name1.hasProblem());
722

    
723
        //Genus //#6030
724
        hybridCache = "Orchis "+UTF8.HYBRID+" Platanthera";
725
        name1 = parser.parseFullName(hybridCache, botanicCode, null);
726
        assertFalse("Name must be parsable", name1.hasProblem());
727
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
728
        assertFalse("Name must not have parsing problems", name1.hasProblem());
729
        assertEquals("Title cache must be correct", hybridCache, name1.getTitleCache());
730
        orderedRels = name1.getOrderedChildRelationships();
731
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
732
        firstParent = orderedRels.get(0).getParentName();
733
        assertEquals("Name must have Orchis as first hybrid parent", "Orchis", firstParent.getTitleCache());
734
        secondParent = orderedRels.get(1).getParentName();
735
        assertEquals("Name must have Platanthera as second hybrid parent", "Platanthera", secondParent.getTitleCache());
736
        assertEquals("Hybrid name must have genus as rank", Rank.GENUS(), name1.getRank());
737

    
738
        name1 = parser.parseReferencedName(hybridCache, botanicCode, null);
739
        assertFalse("Name must not have parsing problems", name1.hasProblem());
740

    
741
        //Subspecies first hybrid
742
        name1 = parser.parseFullName("Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", botanicCode, null);
743
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
744
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
745
        assertEquals("Title cache must be correct", "Abies alba subsp. beta "+UTF8.HYBRID+" Pinus bus", name1.getTitleCache());
746
        orderedRels = name1.getOrderedChildRelationships();
747
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
748
        firstParent = orderedRels.get(0).getParentName();
749
        assertEquals("Name must have Abies alba subsp. beta as first hybrid parent", "Abies alba subsp. beta", firstParent.getTitleCache());
750
        secondParent = orderedRels.get(1).getParentName();
751
        assertEquals("Name must have Pinus bus as second hybrid parent", "Pinus bus", secondParent.getTitleCache());
752
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
753

    
754
        //variety second hybrid
755
        name1 = parser.parseFullName("Abies alba \u00D7 Pinus bus  var. beta", botanicCode, null);
756
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
757
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
758
        assertEquals("Title cache must be correct", "Abies alba \u00D7 Pinus bus var. beta", name1.getTitleCache());
759
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
760

    
761
        //hybrids with authors  //happens but questionable
762
        name1 = parser.parseFullName("Abies alba L. \u00D7 Pinus bus Mill.", botanicCode, null);
763
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
764
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
765
        assertEquals("Title cache must be correct", "Abies alba L. \u00D7 Pinus bus Mill.", name1.getTitleCache());
766
        orderedRels = name1.getOrderedChildRelationships();
767
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
768
        firstParent = orderedRels.get(0).getParentName();
769
        assertEquals("Name must have Abies alba L. as first hybrid parent", "Abies alba L.", firstParent.getTitleCache());
770
        secondParent = orderedRels.get(1).getParentName();
771
        assertEquals("Name must have Pinus bus Mill. as second hybrid parent", "Pinus bus Mill.", secondParent.getTitleCache());
772
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
773

    
774
        //abbreviated genus hybrid formula #6410 / #5983
775
        String nameStr = "Nepenthes mirabilis \u00D7 N. alata";
776
        name1 = parser.parseFullName(nameStr, botanicCode, null);
777
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
778
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
779
        //could also be N. or no genus at all, depends on formatter
780
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
781
        orderedRels = name1.getOrderedChildRelationships();
782
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
783
        firstParent = orderedRels.get(0).getParentName();
784
        //to be discussed as usually they should be ordered alphabetically
785
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
786
        secondParent = orderedRels.get(1).getParentName();
787
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
788
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
789

    
790
        //missing genus hybrid formula #5983
791
        nameStr = "Nepenthes mirabilis \u00D7 alata";
792
        name1 = parser.parseFullName(nameStr, botanicCode, null);
793
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
794
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
795
        //could also be N. or no genus at all, depends on formatter
796
        assertEquals("Title cache must be correct", "Nepenthes mirabilis \u00D7 Nepenthes alata", name1.getTitleCache());
797
        orderedRels = name1.getOrderedChildRelationships();
798
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
799
        firstParent = orderedRels.get(0).getParentName();
800
        //to be discussed as usually they should be ordered alphabetically
801
        assertEquals("Name must have Nepenthes mirabilis as first hybrid parent", "Nepenthes mirabilis", firstParent.getTitleCache());
802
        secondParent = orderedRels.get(1).getParentName();
803
        assertEquals("Name must have Nepenthes alata as second hybrid parent", "Nepenthes alata", secondParent.getTitleCache());
804
        assertEquals("Hybrid name must have the lower rank ('species') as rank", Rank.SPECIES(), name1.getRank());
805

    
806
        //#5983 subsp. with species and missing genus
807
        nameStr = "Orchis coriophora subsp. fragrans \u00D7 sancta";
808
        name1 = parser.parseFullName(nameStr, botanicCode, null);
809
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
810
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
811
        //could also be N. or no genus at all, depends on formatter
812
        assertEquals("Title cache must be correct", "Orchis coriophora subsp. fragrans \u00D7 Orchis sancta", name1.getTitleCache());
813
        orderedRels = name1.getOrderedChildRelationships();
814
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
815
        firstParent = orderedRels.get(0).getParentName();
816
        assertEquals("Name must have Orchis coriophora subsp. fragrans as first hybrid parent", "Orchis coriophora subsp. fragrans", firstParent.getTitleCache());
817
        secondParent = orderedRels.get(1).getParentName();
818
        assertEquals("Name must have Orchis sancta as second hybrid parent", "Orchis sancta", secondParent.getTitleCache());
819
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
820

    
821
        //2 subspecies with missing genus part #5983
822
        nameStr = "Orchis morio subsp. syriaca \u00D7 papilionacea subsp. schirvanica";
823
        name1 = parser.parseFullName(nameStr, botanicCode, null);
824
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
825
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
826
        //could also be N. or no genus at all, depends on formatter
827
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis papilionacea subsp. schirvanica", name1.getTitleCache());
828
        orderedRels = name1.getOrderedChildRelationships();
829
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
830
        firstParent = orderedRels.get(0).getParentName();
831
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
832
        secondParent = orderedRels.get(1).getParentName();
833
        assertEquals("Name must have Orchis papilionacea subsp. schirvanica as second hybrid parent", "Orchis papilionacea subsp. schirvanica", secondParent.getTitleCache());
834
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
835

    
836
        //subspecies and variety with missing genus part
837
        nameStr = "Orchis morio subsp. syriaca \u00D7 papilionacea var. schirvanica";
838
        name1 = parser.parseFullName(nameStr, botanicCode, null);
839
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
840
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
841
        //could also be N. or no genus at all, depends on formatter
842
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis papilionacea var. schirvanica", name1.getTitleCache());
843
        orderedRels = name1.getOrderedChildRelationships();
844
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
845
        firstParent = orderedRels.get(0).getParentName();
846
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
847
        secondParent = orderedRels.get(1).getParentName();
848
        assertEquals("Name must have Orchis papilionacea var. schirvanica as second hybrid parent", "Orchis papilionacea var. schirvanica", secondParent.getTitleCache());
849
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
850

    
851
      //subspecies and variety with genus part
852
        nameStr = "Orchis morio subsp. syriaca \u00D7 Test papilionacea var. schirvanica";
853
        name1 = parser.parseFullName(nameStr, botanicCode, null);
854
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
855
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
856
        //could also be N. or no genus at all, depends on formatter
857
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Test papilionacea var. schirvanica", name1.getTitleCache());
858
        orderedRels = name1.getOrderedChildRelationships();
859
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
860
        firstParent = orderedRels.get(0).getParentName();
861
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
862
        secondParent = orderedRels.get(1).getParentName();
863
        assertEquals("Name must have Orchis papilionacea var. schirvanica as second hybrid parent", "Test papilionacea var. schirvanica", secondParent.getTitleCache());
864
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
865

    
866
        //2 subspecies with missing genus and species part #5983
867
        nameStr = "Orchis morio subsp. syriaca \u00D7 subsp. schirvanica";
868
        name1 = parser.parseFullName(nameStr, botanicCode, null);
869
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
870
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
871
        //could also be N. or no genus at all, depends on formatter
872
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio subsp. schirvanica", name1.getTitleCache());
873
        orderedRels = name1.getOrderedChildRelationships();
874
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
875
        firstParent = orderedRels.get(0).getParentName();
876
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
877
        secondParent = orderedRels.get(1).getParentName();
878
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio subsp. schirvanica", secondParent.getTitleCache());
879
        assertEquals("Hybrid name must have the lower rank ('subspecies') as rank", Rank.SUBSPECIES(), name1.getRank());
880

    
881
        //subspecies and variety with missing genus and species part #5983
882
        nameStr = "Orchis morio subsp. syriaca \u00D7 var. schirvanica";
883
        name1 = parser.parseFullName(nameStr, botanicCode, null);
884
        assertTrue("Name must have hybrid formula bit set", name1.isHybridFormula());
885
        assertEquals("Name must have 2 hybrid parents", 2, name1.getHybridChildRelations().size());
886
        //could also be N. or no genus at all, depends on formatter
887
        assertEquals("Title cache must be correct", "Orchis morio subsp. syriaca \u00D7 Orchis morio var. schirvanica", name1.getTitleCache());
888
        orderedRels = name1.getOrderedChildRelationships();
889
        assertEquals("Name must have 2 hybrid parents in ordered list", 2, orderedRels.size());
890
        firstParent = orderedRels.get(0).getParentName();
891
        assertEquals("Name must have Orchis morio subsp. syriaca as first hybrid parent", "Orchis morio subsp. syriaca", firstParent.getTitleCache());
892
        secondParent = orderedRels.get(1).getParentName();
893
        assertEquals("Name must have Orchis morio subsp. schirvanica as second hybrid parent", "Orchis morio var. schirvanica", secondParent.getTitleCache());
894
        assertEquals("Hybrid name must have the lower rank ('variety') as rank", Rank.VARIETY(), name1.getRank());
895

    
896

    
897
    }
898

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

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

    
912

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

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

    
928

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

    
935

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

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

    
948

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

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

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

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

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

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

    
988

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

    
997

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1215
        //not yet parsed "not avail."
1216
    }
1217

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

    
1231

    
1232
        //null
1233
        String strNull = null;
1234
        Rank rankSpecies = Rank.SPECIES();
1235
        INonViralName nameNull = parser.parseReferencedName(strNull, null, rankSpecies);
1236
        assertNull(nameNull);
1237

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

    
1245

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

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

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

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

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

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

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

    
1341
        assertEquals(NomenclaturalCode.ICZN, nameZooRefNotParsabel.getNameType());
1342
        assertEquals(Integer.valueOf(1923), nameZooRefNotParsabel.getPublicationYear());
1343
        assertEquals(1, nameZooRefNotParsabel.getStatus().size());
1344

    
1345
        String strZooNameSineYear = "Homo sapiens L., 1758, Sp. An. 3: 345";
1346
        IZoologicalName nameZooNameSineYear = parser.parseReferencedName(strZooNameSineYear);
1347
        assertFalse(nameZooNameSineYear.hasProblem());
1348
        assertEquals("Name without reference year must have year", (Integer)1758, nameZooNameSineYear.getPublicationYear());
1349
        assertEquals("Name without reference year must have year", "1758", nameZooNameSineYear.getNomenclaturalReference().getYear());
1350

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

    
1359

    
1360
        //Special MicroRefs
1361
        String strSpecDetail1 = "Abies alba Mill. in Sp. Pl. 4(6): [455]. 1987";
1362
        INonViralName nameSpecDet1 = parser.parseReferencedName(strSpecDetail1 + ".", null, rankSpecies);
1363
        assertFalse(nameSpecDet1.hasProblem());
1364
        assertEquals(strSpecDetail1, nameSpecDet1.getFullTitleCache());
1365
        assertEquals("[455]", nameSpecDet1.getNomenclaturalMicroReference());
1366

    
1367
        //Special MicroRefs
1368
        String strSpecDetail2 = "Abies alba Mill. in Sp. Pl. 4(6): couv. 2. 1987";
1369
        INonViralName nameSpecDet2 = parser.parseReferencedName(strSpecDetail2 + ".", null, rankSpecies);
1370
        assertFalse(nameSpecDet2.hasProblem());
1371
        assertEquals(strSpecDetail2, nameSpecDet2.getFullTitleCache());
1372
        assertEquals("couv. 2", nameSpecDet2.getNomenclaturalMicroReference());
1373

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

    
1381
        //Special MicroRefs
1382
        String strSpecDetail4 = "Abies alba Mill. in Sp. Pl. 4(6): fig. 455-567. 1987";
1383
        fullReference = strSpecDetail4 + ".";
1384
        INonViralName nameSpecDet4 = parser.parseReferencedName(fullReference, null, rankSpecies);
1385
        assertFalse(nameSpecDet4.hasProblem());
1386
        assertEquals(strSpecDetail4, nameSpecDet4.getFullTitleCache());
1387
        assertEquals("fig. 455-567", nameSpecDet4.getNomenclaturalMicroReference());
1388

    
1389

    
1390
        //Special MicroRefs
1391
        String strSpecDetail5 = "Abies alba Mill. in Sp. Pl. 4(6): Gard n\u00B0 4. 1987";
1392
        fullReference = strSpecDetail5 + ".";
1393
        INonViralName nameSpecDet5 = parser.parseReferencedName(fullReference, null, rankSpecies);
1394
        assertFalse(nameSpecDet5.hasProblem());
1395
        assertEquals(strSpecDetail5, nameSpecDet5.getFullTitleCache());
1396
        assertEquals("Gard n\u00B0 4", nameSpecDet5.getNomenclaturalMicroReference());
1397

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

    
1406
        //Special MicroRefs
1407
        String strSpecDetail7 = "Abies alba Mill. in Sp. Pl. 4(6): pp.455-457. 1987";
1408
        fullReference = strSpecDetail7 + ".";
1409
        INonViralName nameSpecDet7 = parser.parseReferencedName(fullReference, null, rankSpecies);
1410
        assertFalse(nameSpecDet7.hasProblem());
1411
        assertEquals(strSpecDetail7, nameSpecDet7.getFullTitleCache());
1412
        assertEquals("pp.455-457", nameSpecDet7.getNomenclaturalMicroReference());
1413

    
1414
        //Special MicroRefs
1415
        String strSpecDetail8 = "Abies alba Mill. in Sp. Pl. 4(6): ppp.455-457. 1987";
1416
        INonViralName nameSpecDet8 = parser.parseReferencedName(strSpecDetail8, null, rankSpecies);
1417
        assertTrue(nameSpecDet8.hasProblem());
1418
        assertEquals(20, nameSpecDet8.getProblemStarts()); //TODO better start behind :
1419
        assertEquals(51, nameSpecDet8.getProblemEnds());   //TODO better stop after -457
1420

    
1421

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

    
1429
        //Special MicroRefs
1430
        String strSpecDetail10 = "Abies alba Mill. in Sp. Pl. 4(6): p 455. 1987";
1431
        INonViralName nameSpecDet10 = parser.parseReferencedName(strSpecDetail10, null, rankSpecies);
1432
        assertFalse(nameSpecDet10.hasProblem());
1433
        assertEquals(strSpecDetail10, nameSpecDet10.getFullTitleCache());
1434
        assertEquals("p 455", nameSpecDet10.getNomenclaturalMicroReference());
1435

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

    
1445

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

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

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

    
1470
        //volume, edition
1471
        strNoVolume = "Abies alba Mill., Sp. Pl. ed. 3, 4(5): 455. 1987";
1472
        nameNoVolume = parser.parseReferencedName(strNoVolume, null, rankSpecies);
1473
        assertFalse(nameNoVolume.hasProblem());
1474
        assertEquals(strNoVolume.replace(" ed.", ", ed."), nameNoVolume.getFullTitleCache());
1475
        assertEquals("4(5)", ((IVolumeReference)(nameNoVolume.getNomenclaturalReference())).getVolume());
1476
        assertEquals("3", ((IBook)(nameNoVolume.getNomenclaturalReference())).getEdition());
1477

    
1478
        String strUnparsableInRef = "Abies alba Mill. in -er46: 455. 1987";
1479
        INonViralName nameUnparsableInRef = parser.parseReferencedName(strUnparsableInRef, null, rankSpecies);
1480
        assertTrue(nameUnparsableInRef.hasProblem());
1481
        list = nameUnparsableInRef.getParsingProblems();
1482
        assertTrue("Unparsable title", list.contains(ParserProblem.UnparsableReferenceTitle));
1483
        assertEquals(strUnparsableInRef, nameUnparsableInRef.getFullTitleCache());
1484
        assertEquals(20, nameUnparsableInRef.getProblemStarts());
1485
        assertEquals(25, nameUnparsableInRef.getProblemEnds());
1486

    
1487

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

    
1498
        String strUnparsableInRef2 = "Hieracium pepsicum L., My Bookkkk 1. 1903";
1499
        INonViralName nameUnparsableInRef2 = parser.parseReferencedName(strUnparsableInRef2, null, rankSpecies);
1500
        assertTrue(nameUnparsableInRef2.hasProblem());
1501
        list = nameUnparsableInRef2.getParsingProblems();
1502
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1503
        assertEquals(strUnparsableInRef2, nameUnparsableInRef2.getFullTitleCache());
1504
        assertEquals(23, nameUnparsableInRef2.getProblemStarts());
1505
        assertEquals(41, nameUnparsableInRef2.getProblemEnds());
1506

    
1507

    
1508
        String strUnparsableInRef3 = "Hieracium pespcim N., My Bookkkk 1. 1902";
1509
        INonViralName nameUnparsableInRef3 = parser.parseReferencedName(strUnparsableInRef3, null, null);
1510
        assertTrue(nameUnparsableInRef3.hasProblem());
1511
        list = nameUnparsableInRef3.getParsingProblems();
1512
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1513
        assertEquals(strUnparsableInRef3, nameUnparsableInRef3.getFullTitleCache());
1514
        assertEquals(22, nameUnparsableInRef3.getProblemStarts());
1515
        assertEquals(40, nameUnparsableInRef3.getProblemEnds());
1516

    
1517
        String strUnparsableInRef4 = "Hieracium pepsicum (Hsllreterto) L., My Bookkkk 1. 1903";
1518
        INonViralName nameUnparsableInRef4 = parser.parseReferencedName(strUnparsableInRef4, null, null);
1519
        assertTrue(nameUnparsableInRef4.hasProblem());
1520
        list = nameUnparsableInRef4.getParsingProblems();
1521
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1522
        assertEquals(strUnparsableInRef4, nameUnparsableInRef4.getFullTitleCache());
1523
        assertEquals(37, nameUnparsableInRef4.getProblemStarts());
1524
        assertEquals(55, nameUnparsableInRef4.getProblemEnds());
1525

    
1526
        String strSameName = "Hieracium pepcum (Hsllreterto) L., My Bokkk 1. 1903";
1527
        INonViralName nameSameName = nameUnparsableInRef4;
1528
        parser.parseReferencedName(nameSameName, strSameName, null, true);
1529
        assertTrue(nameSameName.hasProblem());
1530
        list = nameSameName.getParsingProblems();
1531
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1532
        assertEquals(strSameName, nameSameName.getFullTitleCache());
1533
        assertEquals(35, nameSameName.getProblemStarts());
1534
        assertEquals(51, nameSameName.getProblemEnds());
1535

    
1536
        String strGenusUnparse = "Hieracium L., jlklk";
1537
        INonViralName nameGenusUnparse =
1538
            parser.parseReferencedName(strGenusUnparse, null, null);
1539
        assertTrue(nameGenusUnparse.hasProblem());
1540
        list = nameGenusUnparse.getParsingProblems();
1541
        assertTrue("Problem detail", list.contains(ParserProblem.CheckDetailOrYear));
1542
        assertTrue("Problem uninomial", list.contains(ParserProblem.CheckRank));
1543
        assertEquals(strGenusUnparse, nameGenusUnparse.getFullTitleCache());
1544
        assertEquals(0, nameGenusUnparse.getProblemStarts());
1545
        assertEquals(19, nameGenusUnparse.getProblemEnds());
1546

    
1547
        String strGenusUnparse2 = "Hieracium L., Per Luigi: 44. 1987";
1548
        INonViralName nameGenusUnparse2 =
1549
            parser.parseReferencedName(strGenusUnparse2, null, Rank.FAMILY());
1550
        assertFalse(nameGenusUnparse2.hasProblem());
1551
        assertEquals(strGenusUnparse2, nameGenusUnparse2.getFullTitleCache());
1552
        assertEquals(-1, nameGenusUnparse2.getProblemStarts());
1553
        assertEquals(-1, nameGenusUnparse2.getProblemEnds());
1554

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

    
1567
        String strBookSection = "Hieracium vulgatum subsp. acuminatum (Jord.) Zahn in Schinz & Keller, Fl. Schweiz ed. 2, 2: 288. 1905";
1568
        INonViralName nameBookSection =
1569
            parser.parseReferencedName(strBookSection, null, null);
1570
        assertFalse(nameBookSection.hasProblem());
1571
        assertEquals(strBookSection.replace(" ed.", ", ed."), nameBookSection.getFullTitleCache());
1572
        assertEquals(-1, nameBookSection.getProblemStarts());
1573
        assertEquals(-1, nameBookSection.getProblemEnds());
1574
        assertNull(((IBookSection)nameBookSection.getNomenclaturalReference()).getInBook().getDatePublished().getStart());
1575
        assertEquals("1905", ((IBookSection)nameBookSection.getNomenclaturalReference()).getDatePublished().getYear());
1576

    
1577
        String strXXXs = "Abies alba, Soer der 1987";
1578
        INonViralName problemName = parser.parseReferencedName(strXXXs, null, null);
1579
        assertTrue(problemName.hasProblem());
1580
        list = problemName.getParsingProblems();
1581
        assertTrue("Problem must be name-reference separation", list.contains(ParserProblem.NameReferenceSeparation));
1582
        parser.parseReferencedName(problemName, strBookSection, null, true);
1583
        assertFalse(problemName.hasProblem());
1584

    
1585
        problemName = parser.parseFullName(strXXXs, null, null);
1586
        assertTrue(problemName.hasProblem());
1587
        list = problemName.getParsingProblems();
1588
        assertTrue("Name part must be unparsable", list.contains(ParserProblem.UnparsableNamePart));
1589

    
1590

    
1591
        String testParsable = "Pithecellobium macrostachyum Benth.";
1592
        assertTrue(isParsable(testParsable, ICNAFP));
1593

    
1594
        testParsable = "Pithecellobium macrostachyum (Benth.)";
1595
        assertTrue(isParsable(testParsable, ICNAFP));
1596

    
1597
        testParsable = "Pithecellobium macrostachyum (Benth., 1845)";
1598
        assertTrue(isParsable(testParsable, NomenclaturalCode.ICZN));
1599

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

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

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

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

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

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

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

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

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

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

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

    
1641
        testParsable = "Abies alba Mill. var. alba";
1642
        assertTrue("Autonym problem", isParsable(testParsable, ICNAFP));
1643

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

    
1647

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

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

    
1655

    
1656
    }
1657

    
1658

    
1659
    /**
1660
     * Test author with name parts van, von, de, de la, d', da, del.
1661
     * See also http://dev.e-taxonomy.eu/trac/ticket/3373
1662
     */
1663
    @Test
1664
    public final void  testComposedAuthorNames(){
1665

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

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

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

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

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

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

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

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

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

    
1702
    }
1703

    
1704

    
1705

    
1706
    /**
1707
     * @param testParsable
1708
     * @param icbn
1709
     * @return
1710
     */
1711
    private List<ParserProblem> getProblems(String string, NomenclaturalCode code) {
1712
        List<ParserProblem> result = parser.parseReferencedName(string, code, null).getParsingProblems();
1713
        return result;
1714
    }
1715

    
1716
    private boolean isParsable(String string, NomenclaturalCode code){
1717
        INonViralName name = parser.parseReferencedName(string, code, null);
1718
        return ! name.hasProblem();
1719
    }
1720

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

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

    
1740

    
1741
    @Test
1742
    public void testNeverEndingParsing(){
1743
        //some full titles result in never ending parsing process https://dev.e-taxonomy.eu/trac/ticket/1556
1744

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

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

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

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

    
1776

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

    
1782
    }
1783

    
1784

    
1785
    @Test
1786
    public final void testSeries(){
1787
        //TODO should work also for the original string:  #9014
1788
//        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea, n.s., 9: 31. 1958";
1789
        String parseStr = "Mazus pumilus (Burm.f.) Steenis in Nova Guinea Bla, n.s., 9: 31. 1958";
1790
        INonViralName name = parser.parseReferencedName(parseStr);
1791
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
1792
        Reference nomRef = name.getNomenclaturalReference();
1793
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
1794

    
1795
        assertEquals(ReferenceType.Article, nomRef.getType());
1796
        assertEquals(name.getNomenclaturalMicroReference(), "31");
1797
        //TODO series should be parsed and handled better
1798
        assertEquals("Nova Guinea Bla, n.s.,", nomRef.getInJournal().getAbbrevTitle());
1799
//        assertEquals("n.s.", nomRef.getSeriesPart());
1800
    }
1801

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1965

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

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

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

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

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

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

    
2026

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

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

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

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

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

    
2079

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

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

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

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

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

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

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

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

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

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

    
2174
    }
2175

    
2176

    
2177
    @Test
2178
    public final void testSeriesPart(){
2179
        Pattern seriesPattern = Pattern.compile(NonViralNameParserImplRegExBase.pSeriesPart);
2180
        Matcher matcher = seriesPattern.matcher("ser. 2");
2181
        Assert.assertTrue("", matcher.matches());
2182

    
2183
        matcher = seriesPattern.matcher("n.s.");
2184
        Assert.assertTrue("", matcher.matches());
2185

    
2186
//        matcher = seriesPattern.matcher("a.s.");
2187
//        Assert.assertTrue("", matcher.matches());
2188

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

    
2193
        matcher = seriesPattern.matcher("Ser. C");
2194
        Assert.assertTrue("", matcher.matches());
2195

    
2196
        matcher = seriesPattern.matcher("S\u00E9r. B 1");
2197
        Assert.assertTrue("", matcher.matches());
2198

    
2199
        matcher = seriesPattern.matcher("Jerusalem Ser.");
2200
        Assert.assertTrue("", matcher.matches());
2201

    
2202
        matcher = seriesPattern.matcher("nov. Ser.");
2203
        Assert.assertTrue("", matcher.matches());
2204

    
2205

    
2206

    
2207
    }
2208

    
2209
    /**
2210
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#fullTeams(java.lang.String)}.
2211
     */
2212
    @Test
2213
    public final void testFullTeams() {
2214
        logger.warn("Not yet implemented"); // TODO
2215
    }
2216

    
2217
    /**
2218
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#AuthorshipAndEx(java.lang.String)}.
2219
     * @throws StringNotParsableException
2220
     */
2221
    @Test
2222
    public final void testParseAuthorsTaxonNameString() throws StringNotParsableException {
2223
        INonViralName nvn = TaxonNameFactory.NewZoologicalInstance(null);
2224
        parser.parseAuthors(nvn, "Eckweiler & ten Hagen, 2003");
2225
        Team team = (Team)nvn.getCombinationAuthorship();
2226
        Assert.assertNotNull("Comb. author must not be null", team);
2227
        Assert.assertEquals("Must be team with 2 members", 2, team.getTeamMembers().size());
2228
        Assert.assertEquals("Second member must be 'ten Hagen'", "ten Hagen", team.getTeamMembers().get(1).getTitleCache());
2229

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

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

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

    
2255

    
2256
    }
2257

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

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

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

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

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

    
2290
    }
2291

    
2292

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

    
2304
    }
2305

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

    
2310
        //name only
2311
        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";
2312
        DateTime start = DateTime.now();
2313
        INonViralName name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2314
        DateTime end = DateTime.now();
2315
        Duration duration = new Duration(start, end);
2316
        long seconds = duration.getStandardSeconds();
2317
        //this is the critical part of the test that must not be changed
2318
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2319
        //the following may be discussed
2320
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2321

    
2322

    
2323
        //with reference
2324
        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.";
2325
        start = DateTime.now();
2326
        name = parser.parseReferencedName(nameStr, NomenclaturalCode.ICNAFP, null);
2327
        end = DateTime.now();
2328
        duration = new Duration(start, end);
2329
        seconds = duration.getStandardSeconds();
2330
        //this is the critical part of the test that must not be changed
2331
        Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2332
        //the following may be discussed
2333
        Assert.assertFalse("Name should parse without problems",name.hasProblem());
2334
    }
2335

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

    
2344
        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";
2345
        TeamOrPersonBase[] authorArray = new TeamOrPersonBase[4];
2346
        try {
2347
            DateTime start = DateTime.now();
2348
            parser.fullAuthors(authorStr, authorArray, new Integer[]{1800, null, null, null}, NomenclaturalCode.ICNAFP);
2349
            DateTime end = DateTime.now();
2350
            Duration duration = new Duration(start, end);
2351
            long seconds = duration.getStandardSeconds();
2352
//            System.out.println(seconds);
2353
            //this is the critical part of the test that must not be changed
2354
            Assert.assertTrue("Parsing of name should take less then 3 seconds but took " + seconds, seconds < 3);
2355
        } catch (StringNotParsableException e) {
2356
            e.printStackTrace();
2357
            Assert.fail("Authors should be parsable");
2358
        }
2359

    
2360
    }
2361

    
2362

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

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

    
2379
    /**
2380
     * Test method for {@link eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl#parseCultivar(java.lang.String)}.
2381
     */
2382
    @Test
2383
    public final void testParseCultivar() {
2384
        logger.warn("Not yet implemented"); // TODO
2385
    }
2386

    
2387
    @Test
2388
    public final void testNomenclaturalStatus() {
2389
        IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY(), "Acanthopale", null, null, null, null, null, null, null);
2390
        name.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ALTERNATIVE()));
2391
        IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
2392
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2393
        parser.parseReferencedName(name2, name.getFullTitleCache(), name2.getRank(), true);
2394
        Assert.assertEquals("Title cache should be same. No duplication of nom. status should take place", name.getFullTitleCache(), name2.getFullTitleCache());
2395
    }
2396

    
2397
    @Test
2398
    public final void testSpecificAuthors(){
2399
        //McVaugh
2400
        INonViralName name = parser.parseFullName("Psidium longipes var. orbiculare (O.Berg) McVaugh");
2401
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2402
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2403
        assertEquals( "McVaugh", combinationAuthor.getNomenclaturalTitle());
2404
        TeamOrPersonBase<?> basionymAuthor = name.getBasionymAuthorship();
2405
        assertEquals( "O.Berg", basionymAuthor.getNomenclaturalTitle());
2406

    
2407
//      Campanula rhodensis A. DC.
2408

    
2409
    }
2410

    
2411
    @Test
2412
    public final void testBookSectionAuthors(){
2413
        INonViralName name;
2414
        Reference nomRef;
2415
        String title;
2416
        String str;
2417

    
2418
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2419
        str = "Pancratium sickenbergeri Asch. & Schweinf. in Barbey-Boissier & Barbey, Herb. Levant: 158. 1882";
2420
        name = parser.parseReferencedName(str);
2421
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2422
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2423
        assertEquals( "Asch. & Schweinf.", combinationAuthor.getNomenclaturalTitle());
2424
        nomRef = name.getNomenclaturalReference();
2425
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2426
        assertEquals( "Barbey-Boissier & Barbey", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2427
        title = nomRef.getInReference().getAbbrevTitle();
2428
        assertEquals( "Herb. Levant", title);
2429

    
2430
        name = parser.parseReferencedName("Luzula multiflora subsp. pallescens (Sw.) Reichg. in Van Ooststroom & al., Fl. Neerl. 1: 208. 1964");
2431
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2432
        assertEquals( "Reichg.", name.getCombinationAuthorship().getNomenclaturalTitle());
2433
        nomRef = name.getNomenclaturalReference();
2434
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2435
        assertEquals( "Van Ooststroom & al.", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2436
        title = nomRef.getInReference().getAbbrevTitle();
2437
        assertEquals( "Fl. Neerl.", title);
2438

    
2439
        str = "Salvia pratensis var. albiflora T. Durand in De Wildeman & Durand, Prodr. Fl. Belg. 3: 663. 1899";
2440
        name = parser.parseReferencedName(str);
2441
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2442
        assertEquals( "T. Durand", name.getCombinationAuthorship().getNomenclaturalTitle());
2443
        nomRef = name.getNomenclaturalReference();
2444
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2445
        assertEquals( "De Wildeman & Durand", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2446
        title = nomRef.getInReference().getAbbrevTitle();
2447
        assertEquals( "Prodr. Fl. Belg.", title);
2448

    
2449
        str = "Bravoa Lex. in La Llave & Lexarza, Nov. Veg. Desc. 1: 6. 1824";
2450
        name = parser.parseReferencedName(str);
2451
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2452
        assertEquals( "Lex.", name.getCombinationAuthorship().getNomenclaturalTitle());
2453
        nomRef = name.getNomenclaturalReference();
2454
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2455
        assertEquals( "La Llave & Lexarza", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2456
        title = nomRef.getInReference().getAbbrevTitle();
2457
        assertEquals( "Nov. Veg. Desc.", title);
2458

    
2459
        str = "Thymus trachselianus var. vallicola Heinr. Braun in Dalla Torre & Sarnthein, Fl. Tirol 6(3): 204. 1912";
2460
        name = parser.parseReferencedName(str);
2461
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2462
        nomRef = name.getNomenclaturalReference();
2463
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2464
        assertEquals( "Dalla Torre & Sarnthein", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2465
        title = nomRef.getInReference().getAbbrevTitle();
2466
        assertEquals( "Fl. Tirol", title);
2467

    
2468
        //see #openIssues
2469
//        str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2470
//        name = parser.parseReferencedName(str);
2471
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2472
//        nomRef = name.getNomenclaturalReference();
2473
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2474
//        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2475
//        title = nomRef.getInReference().getAbbrevTitle();
2476
//        assertEquals( "Nova Fl. Portugal", title);
2477
//
2478
//        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2479
//        name = parser.parseReferencedName(str);
2480
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2481
//        nomRef = name.getNomenclaturalReference();
2482
//        assertEquals(ReferenceType.BookSection, nomRef.getType());
2483
//        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2484
//        title = nomRef.getInReference().getAbbrevTitle();
2485
//        assertEquals( "Mount. Fl. Greece", title);
2486

    
2487

    
2488
    }
2489

    
2490

    
2491
    @Test
2492
    public final void testDatePublished(){
2493

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

    
2500
        name = parser.parseReferencedName("Calamintha transsilvanica (J\u00e1v.) So\u00f3 in Acta Bot. Acad. Sci. Hung. 23: 382. 1977 Apr 4");
2501
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2502
        nomRef = name.getNomenclaturalReference();
2503
        assertEquals(ReferenceType.Article, nomRef.getType());
2504
        assertEquals("1977 Apr 4", nomRef.getDatePublished().toString());
2505
        assertEquals(Integer.valueOf(4), nomRef.getDatePublished().getStartMonth());
2506
    }
2507

    
2508

    
2509
    @Test
2510
    public final void testExistingProblems(){
2511
        //Canabio, issue with space
2512
        INonViralName name = parser.parseReferencedName("Machaonia erythrocarpa var. hondurensis (Standl.) Borhidi"
2513
                + " in Acta Bot. Hung. 46 (1-2): 30. 2004");
2514
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2515
        TeamOrPersonBase<?> combinationAuthor = name.getCombinationAuthorship();
2516
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2517
        Reference nomRef = name.getNomenclaturalReference();
2518
        assertEquals(ReferenceType.Article, nomRef.getType());
2519
        assertEquals("46 (1-2)", nomRef.getVolume());
2520

    
2521
        //Canabio, detail with fig.
2522
        name = parser.parseReferencedName("Didymaea floribunda Rzed."
2523
                + " in Bol. Soc. Bot. Mex. 44: 72, fig. 1. 1983");
2524
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2525
        combinationAuthor = name.getCombinationAuthorship();
2526
        assertEquals( "Rzed.", combinationAuthor.getNomenclaturalTitle());
2527
        nomRef = name.getNomenclaturalReference();
2528
        assertEquals(ReferenceType.Article, nomRef.getType());
2529
        assertEquals("44", nomRef.getVolume());
2530
        assertEquals("72, fig. 1", name.getNomenclaturalMicroReference());
2531

    
2532
        //fig with a-c and without dot
2533
        name = parser.parseReferencedName("Deppea guerrerensis Dwyer & Lorence"
2534
                + " in Allertonia 4: 428. fig 4a-c. 1988");  //
2535
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2536
        combinationAuthor = name.getCombinationAuthorship();
2537
        assertEquals( "Dwyer & Lorence", combinationAuthor.getNomenclaturalTitle());
2538
        nomRef = name.getNomenclaturalReference();
2539
        assertEquals(ReferenceType.Article, nomRef.getType());
2540
        assertEquals("4", nomRef.getVolume());
2541
        assertEquals("428. fig 4a-c", name.getNomenclaturalMicroReference());
2542

    
2543
        //issue with EN_DASH (3–4)
2544
        name = parser.parseReferencedName("Arachnothryx tacanensis (Lundell) Borhidi"
2545
              + " in Acta Bot. Hung. 33 (3" + UTF8.EN_DASH + "4): 303. 1987");
2546
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2547
        combinationAuthor = name.getCombinationAuthorship();
2548
        assertEquals( "Borhidi", combinationAuthor.getNomenclaturalTitle());
2549
        nomRef = name.getNomenclaturalReference();
2550
        assertEquals(ReferenceType.Article, nomRef.getType());
2551
        assertEquals("33 (3" + UTF8.EN_DASH + "4)", nomRef.getVolume());
2552
        assertEquals("303", name.getNomenclaturalMicroReference());
2553

    
2554
        //fig with f.
2555
        name = parser.parseReferencedName("Stenotis Terrell"
2556
                + " in Sida 19(4): 901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2. 2001");
2557
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2558
        combinationAuthor = name.getCombinationAuthorship();
2559
        assertEquals( "Terrell", combinationAuthor.getNomenclaturalTitle());
2560
        nomRef = name.getNomenclaturalReference();
2561
        assertEquals(ReferenceType.Article, nomRef.getType());
2562
        assertEquals("19(4)", nomRef.getVolume());
2563
        assertEquals("901" + UTF8.EN_DASH + "911, f. 1" + UTF8.EN_DASH + "2", name.getNomenclaturalMicroReference());
2564

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

    
2576
        //detail with pl. and figs
2577
        name = parser.parseReferencedName("Randia sonorensis Wiggins"
2578
                + " in Contr. Dudley Herb. 3: 75, pl. 19, figs 4-6. 1940");
2579
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2580
        combinationAuthor = name.getCombinationAuthorship();
2581
        assertEquals( "Wiggins", combinationAuthor.getNomenclaturalTitle());
2582
        nomRef = name.getNomenclaturalReference();
2583
        assertEquals(ReferenceType.Article, nomRef.getType());
2584
        assertEquals("3", nomRef.getVolume());
2585
        assertEquals("75, pl. 19, figs 4-6", name.getNomenclaturalMicroReference());
2586

    
2587

    
2588
        //pl
2589
        name = parser.parseReferencedName("Carapichea  Aubl."
2590
                + " in Hist. Pl. Guiane 1: 167, pl. 64. 1775");
2591
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2592
        combinationAuthor = name.getCombinationAuthorship();
2593
        assertEquals( "Aubl.", combinationAuthor.getNomenclaturalTitle());
2594
        nomRef = name.getNomenclaturalReference();
2595
        assertEquals(ReferenceType.Article, nomRef.getType());
2596
        assertEquals("1", nomRef.getVolume());
2597
        assertEquals("167, pl. 64", name.getNomenclaturalMicroReference());
2598

    
2599
        //fig with ,
2600
        name = parser.parseReferencedName("Hoffmannia ixtlanensis Lorence"
2601
                + " in Novon 4: 121. fig. 2a, b. 1994");
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("121. fig. 2a, b", name.getNomenclaturalMicroReference());
2609

    
2610
        //detail with , to number
2611
        name = parser.parseReferencedName("Deppea martinez-calderonii Lorence"
2612
                + " in Allertonia 4: 399. figs 1e, 2. 1988");
2613
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2614
        combinationAuthor = name.getCombinationAuthorship();
2615
        assertEquals( "Lorence", combinationAuthor.getNomenclaturalTitle());
2616
        nomRef = name.getNomenclaturalReference();
2617
        assertEquals(ReferenceType.Article, nomRef.getType());
2618
        assertEquals("4", nomRef.getVolume());
2619
        assertEquals("399. figs 1e, 2", name.getNomenclaturalMicroReference());
2620

    
2621
        //(Suppl.)
2622
        name = parser.parseReferencedName("Manettia costaricensis  Wernham"
2623
                + " in J. Bot. 57(Suppl.): 38. 1919");
2624
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2625
        combinationAuthor = name.getCombinationAuthorship();
2626
        assertEquals( "Wernham", combinationAuthor.getNomenclaturalTitle());
2627
        nomRef = name.getNomenclaturalReference();
2628
        assertEquals(ReferenceType.Article, nomRef.getType());
2629
        assertEquals("57(Suppl.)", nomRef.getVolume());
2630
        assertEquals("38", name.getNomenclaturalMicroReference());
2631

    
2632
        //NY.
2633
        name = parser.parseReferencedName("Crusea psyllioides (Kunth) W.R. Anderson"
2634
                + " in Mem. NY. Bot. Gard. 22: 75. 1972");
2635
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2636
        combinationAuthor = name.getCombinationAuthorship();
2637
        assertEquals( "W.R. Anderson", combinationAuthor.getNomenclaturalTitle());
2638
        nomRef = name.getNomenclaturalReference();
2639
        assertEquals(ReferenceType.Article, nomRef.getType());
2640
        assertEquals("22", nomRef.getVolume());
2641
        assertEquals("75", name.getNomenclaturalMicroReference());
2642

    
2643
        //apostroph word in title
2644
        name = parser.parseReferencedName("Sabicea glabrescens Benth."
2645
                + " in Hooker's J. Bot. Kew Gard. Misc. 3: 219. 1841");
2646
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2647
        combinationAuthor = name.getCombinationAuthorship();
2648
        assertEquals( "Benth.", combinationAuthor.getNomenclaturalTitle());
2649
        nomRef = name.getNomenclaturalReference();
2650
        assertEquals(ReferenceType.Article, nomRef.getType());
2651
        assertEquals("3", nomRef.getVolume());
2652
        assertEquals("219", name.getNomenclaturalMicroReference());
2653

    
2654
        // place published e.g. (Hannover)
2655
        name = parser.parseReferencedName("Pittoniotis trichantha Griseb."
2656
                  + " in Bonplandia (Hannover) 6 (1): 8. 1858");
2657
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2658
        combinationAuthor = name.getCombinationAuthorship();
2659
        assertEquals( "Griseb.", combinationAuthor.getNomenclaturalTitle());
2660
        nomRef = name.getNomenclaturalReference();
2661
        assertEquals(ReferenceType.Article, nomRef.getType());
2662
        assertEquals("6 (1)", nomRef.getVolume());
2663
        assertEquals("8", name.getNomenclaturalMicroReference());
2664

    
2665
        //komplex / incorrect year without quotation marks
2666
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2667
                + " in Acta Bot. Hung. 29(1\u20134): 16, f. 1\u20132, t. 1-8. 1983 [1984]");
2668
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2669
        combinationAuthor = name.getCombinationAuthorship();
2670
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2671
        nomRef = name.getNomenclaturalReference();
2672
        assertEquals(ReferenceType.Article, nomRef.getType());
2673
        assertEquals("29(1\u20134)", nomRef.getVolume());
2674
        assertEquals("16, f. 1\u20132, t. 1-8", name.getNomenclaturalMicroReference());
2675
        assertEquals("1983 [1984]", nomRef.getDatePublishedString());
2676
//        assertEquals("1984", nomRef.getYear()); //was like this, but is not necessarily correct, see #7429
2677

    
2678
        //incorrect year with \u201e \u201f  (s. eu.etaxonomy.cdm.common.UTF8.ENGLISH_QUOT_START
2679
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2680
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \u201e1983\u201f [1984]");
2681
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2682
        combinationAuthor = name.getCombinationAuthorship();
2683
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2684
        nomRef = name.getNomenclaturalReference();
2685
        assertEquals(ReferenceType.Article, nomRef.getType());
2686
        assertEquals("29(1-4)", nomRef.getVolume());
2687
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2688
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2689
        assertEquals("1984", nomRef.getYear());
2690

    
2691
        //incorrect year with "
2692
        name = parser.parseReferencedName("Javorkaea Borhidi & Jarai-Koml."
2693
                + " in Acta Bot. Hung. 29(1-4): 16, f. 1-2. \"1983\" [1984]");
2694
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2695
        combinationAuthor = name.getCombinationAuthorship();
2696
        assertEquals( "Borhidi & Jarai-Koml.", combinationAuthor.getNomenclaturalTitle());
2697
        nomRef = name.getNomenclaturalReference();
2698
        assertEquals(ReferenceType.Article, nomRef.getType());
2699
        assertEquals("29(1-4)", nomRef.getVolume());
2700
        assertEquals("16, f. 1-2", name.getNomenclaturalMicroReference());
2701
        //changed from "1983" [1984] to 1984 ["1983"] after implementing #7429
2702
        assertEquals("1984 [\"1983\"]", nomRef.getDatePublishedString());
2703
        assertEquals("1984", nomRef.getYear());
2704

    
2705
        //fig. a
2706
        name = parser.parseReferencedName("Psychotria capitata  Ruiz & Pav."
2707
                + " in Fl. Peruv. 2: 59, pl. 206, fig. a. 1799");
2708
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2709
        combinationAuthor = name.getCombinationAuthorship();
2710
        assertEquals( "Ruiz & Pav.", combinationAuthor.getNomenclaturalTitle());
2711
        nomRef = name.getNomenclaturalReference();
2712
        assertEquals(ReferenceType.Article, nomRef.getType());
2713
        assertEquals("2", nomRef.getVolume());
2714
        assertEquals("59, pl. 206, fig. a", name.getNomenclaturalMicroReference());
2715

    
2716
        //442A.
2717
        name = parser.parseReferencedName("Rogiera elegans Planch."
2718
                + " in Fl. Serres Jard. Eur. 5: 442A. 1849");
2719
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2720
        combinationAuthor = name.getCombinationAuthorship();
2721
        assertEquals( "Planch.", combinationAuthor.getNomenclaturalTitle());
2722
        nomRef = name.getNomenclaturalReference();
2723
        assertEquals(ReferenceType.Article, nomRef.getType());
2724
        assertEquals("5", nomRef.getVolume());
2725
        assertEquals("442A", name.getNomenclaturalMicroReference());
2726

    
2727
        //f
2728
        name = parser.parseReferencedName("Coussarea imitans L.O. Williams"
2729
                + " in Phytologia 26 (6): 488-489, f. 1973");
2730
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2731
        combinationAuthor = name.getCombinationAuthorship();
2732
        assertEquals( "L.O. Williams", combinationAuthor.getNomenclaturalTitle());
2733
        nomRef = name.getNomenclaturalReference();
2734
        assertEquals(ReferenceType.Article, nomRef.getType());
2735
        assertEquals("26 (6)", nomRef.getVolume());
2736
        assertEquals("488-489, f", name.getNomenclaturalMicroReference());
2737

    
2738
        //Phys.-Med.
2739
        name = parser.parseReferencedName("Coccocypselum cordifolium Nees & Mart."
2740
                + " in Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur. 12: 14. 1824");
2741
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2742
        combinationAuthor = name.getCombinationAuthorship();
2743
        assertEquals( "Nees & Mart.", combinationAuthor.getNomenclaturalTitle());
2744
        nomRef = name.getNomenclaturalReference();
2745
        assertEquals(ReferenceType.Article, nomRef.getType());
2746
        assertEquals("Nova Acta Phys.-Med. Acad. Caes.\u2013Leop. Nat. Cur.", nomRef.getInReference().getAbbrevTitle());
2747
        assertEquals("12", nomRef.getVolume());
2748
        assertEquals("14", name.getNomenclaturalMicroReference());
2749
        assertEquals("1824", nomRef.getYear());
2750

    
2751
        //(ed. 10)  wanted?
2752
//        Syst. Nat. (ed. 10) 2: 930. 1759
2753
//        name = parser.parseReferencedName("Erithalis fruticosa L."
2754
//                + ", Syst. Nat. ed. 10, 2: 930. 1759");
2755
//        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2756
//        combinationAuthor = name.getCombinationAuthorship();
2757
//        assertEquals( "L.", combinationAuthor.getNomenclaturalTitle());
2758
//        nomRef = (Reference)name.getNomenclaturalReference();
2759
//        assertEquals(ReferenceType.Book, nomRef.getType());
2760
//        assertEquals("2", nomRef.getVolume());
2761
//        assertEquals("10", nomRef.getEdition());
2762
//        assertEquals("930", name.getNomenclaturalMicroReference());
2763
//        assertEquals("1759", nomRef.getYear());
2764

    
2765
        //issue with letter "(1a)"
2766
        name = parser.parseReferencedName("Arthraerua (Kuntze) Schinz,"
2767
                + " Nat. Pflanzenfam. 3(1a): 109. 1893");
2768
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2769
        combinationAuthor = name.getCombinationAuthorship();
2770
        assertEquals( "Schinz", combinationAuthor.getNomenclaturalTitle());
2771
        nomRef = name.getNomenclaturalReference();
2772
        Assert.assertFalse("Reference should be parsable", nomRef.isProtectedTitleCache());
2773
        assertEquals(ReferenceType.Book, nomRef.getType());
2774
        assertEquals("Nat. Pflanzenfam.", nomRef.getAbbrevTitle());
2775
        assertEquals("3(1a)", nomRef.getVolume());
2776
        assertEquals("109", name.getNomenclaturalMicroReference());
2777
        assertEquals("1893", nomRef.getYear());
2778

    
2779
        //Accent graph in author name #6057
2780
        name = parser.parseReferencedName("Sedum plicatum O`Brian");
2781
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2782
        assertEquals( "O`Brian", name.getCombinationAuthorship().getNomenclaturalTitle());
2783

    
2784
        //-e-  #6060
2785
        name = parser.parseReferencedName("Thamniopsis stenodictyon (Sehnem) Oliveira-e-Silva & O.Yano");
2786
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2787
        Team team = (Team)name.getCombinationAuthorship();
2788
        assertEquals( "Oliveira-e-Silva", team.getTeamMembers().get(0).getNomenclaturalTitle());
2789

    
2790
        //Vorabdr.
2791
        name = parser.parseReferencedName("Ophrys hystera  Kreutz & Ruedi Peter in J. Eur. Orchideen 30(Vorabdr.): 128. 1997");
2792
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2793
        assertEquals( "30(Vorabdr.)", name.getNomenclaturalReference().getVolume());
2794

    
2795
        //#6100  jun.
2796
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2797
        name = parser.parseFullName(nameStr, botanicCode, null);  //fails with missing botanicCode, see open issues
2798
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2799
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2800

    
2801
        //#6100 bis /ter
2802
        nameStr = "Schistidium aquaticum (R.Br.ter) Ochyra";
2803
        name = parser.parseFullName(nameStr);
2804
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2805
        assertEquals( "R.Br.ter", name.getBasionymAuthorship().getTitleCache());
2806

    
2807
        nameStr = "Grimmia mitchellii R.Br.bis";
2808
        name = parser.parseFullName(nameStr);
2809
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2810
        assertEquals( "R.Br.bis", name.getCombinationAuthorship().getTitleCache());
2811

    
2812
        //forma #6100
2813
        nameStr = "Xerocomus parasiticus forma piperatoides (J. Blum) R. Mazza";
2814
        name = parser.parseFullName(nameStr);
2815
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2816
        assertEquals( "piperatoides", name.getInfraSpecificEpithet());
2817
        assertEquals( Rank.FORM(), name.getRank());
2818

    
2819
        //subgen. #6100
2820
        nameStr = "Aliciella subgen. Gilmania (H.Mason & A.D.Grant) J.M.Porter";
2821
        name = parser.parseFullName(nameStr);
2822
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2823
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2824
        assertEquals( Rank.SUBGENUS(), name.getRank());
2825

    
2826
        //subgen. #6100
2827
        nameStr = "Aliciella subgen. Gilmania J.M.Porter";
2828
        name = parser.parseFullName(nameStr);
2829
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2830
        assertEquals( "Gilmania", name.getInfraGenericEpithet());
2831
        assertEquals( Rank.SUBGENUS(), name.getRank());
2832
        assertEquals( "J.M.Porter", name.getCombinationAuthorship().getTitleCache());
2833

    
2834
        //la Croix #6100
2835
        nameStr = "Eulophia ovalis var. bainesii (Rolfe) P.J.Cribb & la Croix";
2836
        name = parser.parseFullName(nameStr);
2837
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2838
        assertEquals( "P.J.Cribb & la Croix", name.getCombinationAuthorship().getTitleCache());
2839

    
2840
        //I = Yi #6100
2841
        nameStr = "Parasenecio hwangshanicus (P.I Mao) C.I Peng";
2842
        name = parser.parseFullName(nameStr);
2843
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2844
        assertEquals("I (=Yi) should be an accepted ending", "C.I Peng", name.getCombinationAuthorship().getTitleCache());
2845
        assertEquals("I (=Yi) should be an accepted ending", "P.I Mao", name.getBasionymAuthorship().getTitleCache());
2846

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

    
2854
        //Man in 't Veld  #6100
2855
        nameStr = "Phytophthora multivesiculata Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters";
2856
        name = parser.parseFullName(nameStr);
2857
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2858
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & al.",
2859
                name.getCombinationAuthorship().getTitleCache());
2860
        assertEquals("Ilieva, Man in 't Veld, Veenbaas-Rijks & Pieters",
2861
                name.getCombinationAuthorship().getNomenclaturalTitle());
2862

    
2863
        nameStr = "Thymus \u00D7 herberoi De la Torre, Vicedo, Alonso & Paya";
2864
        name = parser.parseFullName(nameStr);
2865
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2866
        assertEquals("De la Torre, Vicedo, Alonso & al.",
2867
                name.getCombinationAuthorship().getTitleCache());
2868
        assertEquals("De la Torre, Vicedo, Alonso & Paya",
2869
                name.getCombinationAuthorship().getNomenclaturalTitle());
2870

    
2871
        //Sant'Anna
2872
        nameStr = "Coelosphaerium evidenter-marginatum M.T.P.Azevedo & Sant'Anna";
2873
        name = parser.parseFullName(nameStr);
2874
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2875
        assertEquals("M.T.P.Azevedo & Sant'Anna", name.getCombinationAuthorship().getTitleCache());
2876

    
2877
        //Heft
2878
        nameStr = "Nepenthes deaniana Macfarl. in Engl., Mein Pflanzenr. IV. 111 (Heft 36): 57. 1908.";
2879
        name = parser.parseReferencedName(nameStr);
2880
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2881
        Reference ref = name.getNomenclaturalReference();
2882
        Assert.assertFalse("Reference should be parsable", ref.hasProblem());
2883
        //or even better IV. 111 (Heft 36), but this is currently not implemented
2884
        assertEquals("111 (Heft 36)", ref.getInReference().getVolume());
2885

    
2886
        //journal with commata at pos 4
2887
        nameStr = "Bufonia kotschyana subsp. densa Chrtek & Krisa in Acta Univ.Carol., Biol. 43(2): 105. 1999";
2888
        name = parser.parseReferencedName(nameStr);
2889
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2890
        String author = name.getAuthorshipCache();
2891
        assertEquals("Chrtek & Krisa", author);
2892
        ref = name.getNomenclaturalReference();
2893
        Assert.assertNotNull("Nomenclatural reference should be an article and therefore have an in reference", ref.getInReference());
2894
        Assert.assertEquals(ReferenceType.Journal, ref.getInReference().getType());
2895

    
2896
    }
2897

    
2898
    @Test
2899
    @Ignore
2900
    public final void openIssues(){
2901
        //#6100  jun.
2902
        String nameStr = "Swida \u00D7 friedlanderi (W.H.Wagner jun.) Holub";
2903
        INonViralName name = parser.parseFullName(nameStr, botanicCode, null);
2904
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2905
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2906
        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
2907
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2908
        assertEquals( "W.H.Wagner jun.", name.getBasionymAuthorship().getTitleCache());
2909

    
2910
        //´t Hart #6100
2911
        nameStr = "Sedum decipiens (Baker) Thiede & \u00B4t Hart";   //still does not work with "´" if compiled by maven, don't know what the difference is
2912
        name = parser.parseFullName(nameStr);
2913
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2914
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2915
                "Thiede & \u00B4t Hart", name.getCombinationAuthorship().getTitleCache());
2916
        nameStr = "Sedum decipiens (Baker) Thiede & ´t Hart";   //does not work if compiled with maven
2917
        name = parser.parseFullName(nameStr);
2918
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2919
        assertEquals("All types of quotation marks should be accepted, though better match it to standard ' afterwards",
2920
                "Thiede & ´t Hart", name.getCombinationAuthorship().getTitleCache());
2921

    
2922
        //should be recognized as book section (see testBookSectionAuthors)
2923
        String str = "Iris xiphium var. lusitanica (Ker Gawl.) Franco in Amaral Franco & Rocha Afonso, Nova Fl. Portugal 3: 135. 1994";
2924
        name = parser.parseReferencedName(str);
2925
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2926
        Reference nomRef = name.getNomenclaturalReference();
2927
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2928
        assertEquals( "Amaral Franco & Rocha Afonso", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2929
        assertEquals( "Nova Fl. Portugal", nomRef.getInReference().getAbbrevTitle());
2930

    
2931
        //same
2932
        str = "Fritillaria mutabilis Kamari in Strid & Kit Tan, Mount. Fl. Greece 2: 679. 1991";
2933
        name = parser.parseReferencedName(str);
2934
        Assert.assertFalse("Name should be parsable", name.isProtectedTitleCache());
2935
        nomRef = name.getNomenclaturalReference();
2936
        assertEquals(ReferenceType.BookSection, nomRef.getType());
2937
        assertEquals( "Strid & Kit Tan", nomRef.getInReference().getAuthorship().getNomenclaturalTitle());
2938
        assertEquals( "Mount. Fl. Greece", nomRef.getInReference().getAbbrevTitle());
2939
    }
2940

    
2941
}
(2-2/4)