dimus-biodiversity 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,80 @@
1
+ grammar ScientificNameDirty
2
+ include ScientificNameClean
3
+
4
+ rule composite_scientific_name
5
+ super
6
+ end
7
+
8
+ # rule original_authors_names_full
9
+ # super
10
+ # end
11
+ #
12
+ # rule incorrect_original_authors_names
13
+ # "[" space a:authors_names_full space "]" {
14
+ # def value
15
+ # "(" + a.value + ")"
16
+ # end
17
+ # def details
18
+ # {:orig_authors => a.details[:authors]}
19
+ # end
20
+ # }
21
+ # end
22
+
23
+ rule year
24
+ a:[\d]+ space b:approximate_year {
25
+ def value
26
+ a.text_value + " " + b.text_value
27
+ end
28
+ def details
29
+ {:ambiguous_year => value}
30
+ end
31
+ }
32
+ /
33
+ a:[\d]+ page_number
34
+ {
35
+ def value
36
+ a.text_value
37
+ end
38
+ def details
39
+ {:year => value}
40
+ end
41
+ }
42
+ /
43
+ double_year
44
+ /
45
+ approximate_year
46
+ /
47
+ super
48
+ end
49
+
50
+ rule approximate_year
51
+ "[" space a:([\d] [\d] [\d] [\d\?]+) space "]"+ {
52
+ def value
53
+ "(" + a.text_value + ")"
54
+ end
55
+ def details
56
+ {:approximate_year => value}
57
+ end
58
+ }
59
+ end
60
+
61
+ rule double_year
62
+ [0-9] [0-9A-Za-z\?\-]+ {
63
+ def value
64
+ text_value
65
+ end
66
+ def details
67
+ {:year => value}
68
+ end
69
+ }
70
+ end
71
+
72
+ rule page_number
73
+ ":" space [\d]+
74
+ {
75
+ def value
76
+ end
77
+ }
78
+ end
79
+
80
+ end
@@ -1,12 +1,13 @@
1
- # encoding: UTF-8
2
- dir = File.dirname("__FILE__")
3
1
  require 'rubygems'
4
2
  require 'spec'
5
3
  require 'treetop'
4
+ require 'yaml'
6
5
 
7
- Treetop.load(File.expand_path(dir + '../../lib/biodiversity/parser/scientific_name'))
6
+ #NOTE: this spec needs compiled treetop files.
7
+ dir = File.dirname("__FILE__")
8
+ require File.expand_path(dir + '../../lib/biodiversity/parser')
8
9
 
9
- describe ScientificName do
10
+ describe ScientificNameClean do
10
11
  before(:all) do
11
12
  @parser = ScientificNameParser.new
12
13
  end
@@ -27,263 +28,24 @@ describe ScientificName do
27
28
  parse(input).details
28
29
  end
29
30
 
30
- it 'should parse uninomial' do
31
- sn = 'Pseudocercospora'
32
- parse(sn).should_not be_nil
33
- value(sn).should == 'Pseudocercospora'
34
- canonical(sn).should == 'Pseudocercospora'
35
- details(sn).should == {:uninomial=>"Pseudocercospora"}
36
- end
37
-
38
- it 'should parse canonical' do
31
+ it 'should parse accurate name' do
39
32
  sn = 'Pseudocercospora dendrobii'
40
33
  parse(sn).should_not be_nil
41
34
  value(sn).should == 'Pseudocercospora dendrobii'
42
35
  canonical(sn).should == 'Pseudocercospora dendrobii'
43
36
  details(sn).should == {:species=>"dendrobii", :genus=>"Pseudocercospora"}
37
+ canonical('Quoyula').should == 'Quoyula'
38
+ parse('Perissandra laotica').should_not be_nil
44
39
  end
45
40
 
46
- it 'should parse subgenus ZOOLOGICAL' do
47
- sn = "Doriteuthis (Amerigo) pealeii Author 1999"
48
- parse(sn).should_not be_nil
49
- value(sn).should == "Doriteuthis (Amerigo) pealeii Author 1999"
50
- canonical(sn).should == "Doriteuthis pealeii"
51
- details(sn).should == {:subgenus=>"Amerigo", :authors=>{:year=>"1999", :names=>["Author"]}, :species=>"pealeii", :genus=>"Doriteuthis"}
52
- end
53
-
54
- it 'should parse æ in the name' do
55
- names = [
56
- ["Læptura laetifica Dow, 1913", "Laeptura laetifica Dow 1913"],
57
- ["Leptura lætifica Dow, 1913", "Leptura laetifica Dow 1913"],
58
- ["Leptura leætifica Dow, 1913", "Leptura leaetifica Dow 1913"],
59
- ["Leæptura laetifica Dow, 1913", "Leaeptura laetifica Dow 1913"],
60
- ["Leœptura laetifica Dow, 1913", "Leoeptura laetifica Dow 1913"]
61
- ]
62
- names.each do |name_pair|
63
- parse(name_pair[0]).should_not be_nil
64
- value(name_pair[0]).should == name_pair[1]
65
- end
66
- end
67
-
68
- it 'should parse year' do
69
- sn = "Platypus bicaudatulus Schedl 1935"
70
- parse(sn).should_not be_nil
71
- value(sn).should == "Platypus bicaudatulus Schedl 1935"
72
- sn = "Platypus bicaudatulus Schedl, 1935h"
73
- parse(sn).should_not be_nil
74
- value(sn).should == "Platypus bicaudatulus Schedl 1935"
75
- details(sn).should == {:genus=>"Platypus", :species=>"bicaudatulus", :authors=>{:names=>["Schedl"], :year=>"1935"}}
76
- parse("Platypus bicaudatulus Schedl, 1935B").should_not be_nil
77
- end
78
-
79
- it 'should parse species autonym for complex subspecies authorships' do
80
- parse("Aus bus Linn. var. bus").should_not be_nil
81
- details("Aus bus Linn. var. bus").should == {:species=>"bus", :species_authors=>{:authors=>{:names=>["Linn."]}}, :genus=>"Aus", :subspecies=>[{:rank=>"var.", :value=>"bus"}]}
82
- parse("Agalinis purpurea (L.) Briton var. borealis (Berg.) Peterson 1987").should_not be_nil
83
- details("Agalinis purpurea (L.) Briton var. borealis (Berg.) Peterson 1987").should == {:species=>"purpurea", :genus=>"Agalinis", :species_authors=>{:orig_authors=>{:names=>["L."]}, :authors=>{:names=>["Briton"]}}, :subspecies_authors=>{:orig_authors=>{:names=>["Berg."]}, :authors=>{:year=>"1987", :names=>["Peterson"]}}, :subspecies=>[{:value=>"borealis", :rank=>"var."}]}
84
- end
85
-
86
- it 'should parse several authors' do
87
- sn = "Pseudocercospora dendrobii U. Braun & Crous"
88
- parse(sn).should_not be_nil
89
- value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
90
- canonical(sn).should == "Pseudocercospora dendrobii"
91
- details(sn).should == {
92
- :authors=>{:names=>["U. Braun","Crous"]},
93
- :species=>"dendrobii",
94
- :genus=>"Pseudocercospora"}
95
- sn = "Pseudocercospora dendrobii U. Braun and Crous"
96
- parse(sn).should_not be_nil
97
- value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
98
- sn = "Pseudocercospora dendrobii U. Braun et Crous"
99
- parse(sn).should_not be_nil
100
- value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
101
- end
102
-
103
- it 'should parse several authors with a year' do
104
- sn = "Pseudocercospora dendrobii U. Braun & Crous 2003"
105
- parse(sn).should_not be_nil
106
- value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous 2003"
107
- canonical(sn).should == "Pseudocercospora dendrobii"
108
- details(sn).should == {
109
- :authors=>{:names=>["U. Braun","Crous"], :year => "2003"},
110
- :species=>"dendrobii",
111
- :genus=>"Pseudocercospora"}
112
- sn = "Pseudocercospora dendrobii Crous, 2003"
113
- parse(sn).should_not be_nil
114
- parse("Zophosis persis (Chatanay, 1914)").should_not be_nil
115
- parse("Zophosis persis (Chatanay 1914)").should_not be_nil
116
- parse("Zophosis persis (Chatanay), 1914").should_not be_nil
117
- value("Zophosis persis (Chatanay), 1914").should == "Zophosis persis (Chatanay 1914)"
118
- details("Zophosis persis (Chatanay), 1914").should == {:genus=>"Zophosis", :species=>"persis", :orig_authors=>{:names=>["Chatanay"]}, :year=>"1914"}
119
-
120
- parse("Zophosis persis (Chatanay) 1914").should_not be_nil
121
- #parse("Zophosis persis Chatanay (1914)").should_not be_nil
122
- end
123
-
124
- it 'should parse scientific name' do
125
- parse("Pseudocercospora dendrobii (H.C. Burnett) U. Braun & Crous 2003").should_not be_nil
126
- value("Pseudocercospora dendrobii(H.C. Burnett)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii (H.C. Burnett) U. Braun et Crous 2003"
127
- canonical("Pseudocercospora dendrobii(H.C. Burnett)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii"
128
- {:orig_authors=>{:names=>["H.C. Burnett"]}, :species=>"dendrobii", :authors=>{:year=>"2003", :names=>["U. Braun", "Crous"]}, :genus=>"Pseudocercospora"}
129
-
130
- parse("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should_not be_nil
131
- value("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should == "Stagonospora polyspora M.T. Lucas et Sousa da Câmara 1934"
132
- details("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should == {:authors=>{:year=>"1934", :names=>["M.T. Lucas", "Sousa da C\303\242mara"]}, :species=>"polyspora", :genus=>"Stagonospora"}
133
-
134
- parse("Cladoniicola staurospora Diederich, van den Boom & Aptroot 2001").should_not be_nil
135
- parse("Yarrowia lipolytica var. lipolytica (Wick., Kurtzman & E.A. Herrm.) Van der Walt & Arx 1981").should_not be_nil
136
- value("Yarrowia lipolytica var. lipolytica (Wick., Kurtzman & E.A. Herrm.) Van der Walt & Arx 1981").should == "Yarrowia lipolytica var. lipolytica (Wick., Kurtzman et E.A. Herrm.) Van der Walt et Arx 1981"
137
- parse("Physalospora rubiginosa (Fr.) anon.").should_not be_nil
138
- parse("Pleurotus ëous (Berk.) Sacc. 1887").should_not be_nil
139
- parse("Lecanora wetmorei Śliwa 2004").should_not be_nil
140
- # valid
141
- # infraspecific
142
- parse("Calicium furfuraceum * furfuraceum (L.) Pers. 1797").should_not be_nil
143
- parse("Exobasidium vaccinii ** andromedae (P. Karst.) P. Karst. 1882").should_not be_nil
144
- parse("Urceolaria scruposa **** clausa Flot. 1849").should_not be_nil
145
- parse("Cortinarius angulatus B gracilescens Fr. 1838").should_not be_nil
146
- parse("Cyathicula scelobelonium").should_not be_nil
147
- # single quote that did not show
148
- # parse("Phytophthora hedraiandra De Cock & Man in ?t Veld 2004"
149
- # Phthora vastatrix d?Hérelle 1909
150
- # author is exception
151
- parse("Tuber liui A S. Xu 1999").should_not be_nil
152
- parse("Agaricus squamula Berk. & M.A. Curtis 1860").should_not be_nil
153
- parse("Peltula coriacea Büdel, Henssen & Wessels 1986").should_not be_nil
154
- #had to add no dot rule for trinomials without a rank to make it to work
155
- parse("Saccharomyces drosophilae anon.").should_not be_nil
156
- details("Saccharomyces drosophilae anon.").should == {:genus=>"Saccharomyces", :species=>"drosophilae", :authors=>{:names=>["anon."]}}
157
- end
158
-
159
- it 'should parse several authors with several years' do
160
- parse("Pseudocercospora dendrobii (H.C. Burnett 1883) U. Braun & Crous 2003").should_not be_nil
161
- value("Pseudocercospora dendrobii(H.C. Burnett1883)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii (H.C. Burnett 1883) U. Braun et Crous 2003"
162
- canonical("Pseudocercospora dendrobii(H.C. Burnett 1883)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii"
163
- details("Pseudocercospora dendrobii(H.C. Burnett 1883)U. Braun & Crous 2003").should == {:orig_authors=>{:year=>"1883", :names=>["H.C. Burnett"]}, :species=>"dendrobii", :authors=>{:year=>"2003", :names=>["U. Braun", "Crous"]}, :genus=>"Pseudocercospora"}
164
- end
165
-
166
- it 'should not parse serveral authors groups with several years NOT CORRECT' do
167
- parse("Pseudocercospora dendrobii (H.C. Burnett 1883) (Leight.) (Movss. 1967) U. Braun & Crous 2003").should be_nil
168
- end
169
-
170
-
171
- it 'should parse utf-8 name' do
172
- parse("Trematosphaeria phaeospora (E. Müll.) L. Holm 1957").should_not be_nil
173
- value("Trematosphaeria phaeospora ( E. Müll. )L. Holm 1957").should == "Trematosphaeria phaeospora (E. Müll.) L. Holm 1957"
174
- canonical("Trematosphaeria phaeospora(E. Müll.) L. Holm 1957").should == "Trematosphaeria phaeospora"
175
- details("Trematosphaeria phaeospora(E. Müll.) L. Holm 1957 ").should == {:orig_authors=>{:names=>["E. M\303\274ll."]}, :species=>"phaeospora", :authors=>{:year=>"1957", :names=>["L. Holm"]}, :genus=>"Trematosphaeria"}
176
- end
177
-
178
- it "should parse name with f." do
179
- parse("Sphaerotheca fuliginea f. dahliae Movss. 1967").should_not be_nil
180
- value(" Sphaerotheca fuliginea f. dahliae Movss. 1967 ").should == "Sphaerotheca fuliginea f. dahliae Movss. 1967"
181
- canonical("Sphaerotheca fuliginea f. dahliae Movss. 1967").should == "Sphaerotheca fuliginea dahliae"
182
- details("Sphaerotheca fuliginea f. dahliae Movss. 1967").should == {:subspecies=>[{:rank=>"f.", :value=>"dahliae"}], :authors=>{:year=>"1967", :names=>["Movss."]}, :species=>"fuliginea", :genus=>"Sphaerotheca"}
183
- end
184
-
185
- it "should parse name with var." do
186
- parse("Phaeographis inusta var. macularis (Leight.) A.L. Sm. 1861").should_not be_nil
187
- value("Phaeographis inusta var. macularis(Leight.) A.L. Sm. 1861").should == "Phaeographis inusta var. macularis (Leight.) A.L. Sm. 1861"
188
- canonical("Phaeographis inusta var. macularis(Leight.) A.L. Sm. 1861").should == "Phaeographis inusta macularis"
189
- end
190
-
191
- it "should parse name with several subspecies names NOT BOTANICAL CODE BUT NOT INFREQUENT" do
192
- parse("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should_not be_nil
193
- value("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should == "Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall et D.E. Stuntz 1972"
194
- details("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should == {:orig_authors=>{:names=>["Banker"]}, :subspecies=>[{:rank=>"var.", :value=>"zonatum"}, {:rank=>"f.", :value=>"parvum"}], :species=>"scrobiculatum", :authors=>{:year=>"1972", :names=>["D. Hall", "D.E. Stuntz"]}, :genus=>"Hydnellum", :is_valid=>false}
195
- end
196
-
197
- it "should parse status BOTANICAL RARE" do
198
- #it is always latin abbrev often 2 words
199
- parse("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should_not be_nil
200
- value("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == "Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov."
201
- canonical("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == "Arthopyrenia hyalospora"
202
- details("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == {:status=>"comb. nov.", :orig_authors=>{:names=>["Nyl."]}, :species=>"hyalospora", :authors=>{:names=>["R.C. Harris"]}, :genus=>"Arthopyrenia"}
203
- end
204
-
205
- it "should parse name without a year but with authors" do
206
- parse("Arthopyrenia hyalospora (Nyl.) R.C. Harris").should_not be_nil
207
- value("Arthopyrenia hyalospora(Nyl.)R.C. Harris").should == "Arthopyrenia hyalospora (Nyl.) R.C. Harris"
208
- canonical("Arthopyrenia hyalospora (Nyl.) R.C. Harris").should == "Arthopyrenia hyalospora"
209
- end
210
-
211
- it "should parse revised (ex) names" do
212
- #invalidly published
213
- parse("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should_not be_nil
214
- value("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == "Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris"
215
- canonical("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == "Arthopyrenia hyalospora"
216
- details("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == {:species=>"hyalospora", :authors=>{:names=>["R.C. Harris"]}, :genus=>"Arthopyrenia", :original_revised_name_authors=>{:authors=>{:names=>["Banker"]}, :revised_authors=>{:names=>["Nyl."]}}}
217
- parse("Arthopyrenia hyalospora Nyl. ex Banker").should_not be_nil
218
-
219
- parse("Glomopsis lonicerae Peck ex C.J. Gould 1945").should_not be_nil
220
- details("Glomopsis lonicerae Peck ex C.J. Gould 1945").should == {:revised_name_authors=>{:authors=>{:year=>"1945", :names=>["C.J. Gould"]}, :revised_authors=>{:names=>["Peck"]}}, :species=>"lonicerae", :genus=>"Glomopsis"}
221
-
222
- parse("Acanthobasidium delicatum (Wakef.) Oberw. ex Jülich 1979").should_not be_nil
223
- parse("Mycosphaerella eryngii (Fr. ex Duby) Johanson ex Oudem. 1897").should_not be_nil
224
- details("Mycosphaerella eryngii (Fr. ex Duby) Johanson ex Oudem. 1897").should == {:original_revised_name_authors=>{:authors=>{:names=>["Duby"]}, :revised_authors=>{:names=>["Fr."]}}, :species=>"eryngii", :genus=>"Mycosphaerella", :revised_name_authors=>{:authors=>{:year=>"1897", :names=>["Oudem."]}, :revised_authors=>{:names=>["Johanson"]}}}
225
- #invalid but happens
226
- parse("Mycosphaerella eryngii (Fr. Duby) ex Oudem. 1897").should_not be_nil
227
- parse("Mycosphaerella eryngii (Fr.ex Duby) ex Oudem. 1897").should_not be_nil
228
- parse("Salmonella werahensis (Castellani) Hauduroy and Ehringer in Hauduroy 1937").should_not be_nil
41
+ it 'should parse inaccurate name' do
42
+ parse("Tridentella tangeroae Bruce, 198?").should_not be_nil
229
43
  end
230
44
 
231
- it "should parse multiplication sign" do
232
- parse("Arthopyrenia x hyalospora (Nyl.) R.C. Harris").should_not be_nil
233
- details("Arthopyrenia x hyalospora (Nyl. ex Banker) R.C. Harris").should == {:original_revised_name_authors=>{:authors=>{:names=>["Banker"]}, :revised_authors=>{:names=>["Nyl."]}}, :species=>"hyalospora", :authors=>{:names=>["R.C. Harris"]}, :genus=>"Arthopyrenia", :cross=>"inside"}
234
- parse("Arthopyrenia X hyalospora(Nyl. ex Banker) R.C. Harris").should_not be_nil
235
- parse("x Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should_not be_nil
236
- details("x Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == {:original_revised_name_authors=>{:authors=>{:names=>["Banker"]}, :revised_authors=>{:names=>["Nyl."]}}, :species=>"hyalospora", :authors=>{:names=>["R.C. Harris"]}, :genus=>"Arthopyrenia", :cross=>"before"}
237
- parse("X Arthopyrenia (Nyl. ex Banker) R.C. Harris").should_not be_nil
238
- details("X Arthopyrenia (Nyl. ex Banker) R.C. Harris").should == {:uninomial=>"Arthopyrenia", :original_revised_name_authors=>{:authors=>{:names=>["Banker"]}, :revised_authors=>{:names=>["Nyl."]}}, :authors=>{:names=>["R.C. Harris"]}, :cross=>"before"}
239
- #ascii for multiplication
240
- parse("Melampsora × columbiana G. Newc. 2000").should_not be_nil
45
+ it 'should parse name that cannot be fully parsed' do
46
+ parse("Plantago major ESEFDSlj sdafsladjfasd fd ;asldfjasfas#&^&*^*^&}}").should_not be_nil
47
+ canonical('Plantago major ESEFDSlj sdafsladjfasd fd ;asldfjasfas#&^&*^*^&}}').should == 'Plantago major'
241
48
  end
242
49
 
243
- it "should parse hybrid combination" do
244
- parse("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should_not be_nil
245
- value("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
246
- canonical("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
247
- details("Arthopyrenia hyalospora x Hydnellum scrobiculatum").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>{:species=>"scrobiculatum", :genus=>"Hydnellum"}}}
248
-
249
- parse("Arthopyrenia hyalospora (Banker) D. Hall x Hydnellum scrobiculatum D.E. Stuntz").should_not be_nil
250
- value("Arthopyrenia hyalospora (Banker) D. Hall X Hydnellum scrobiculatum D.E. Stuntz").should == "Arthopyrenia hyalospora (Banker) D. Hall \303\227 Hydnellum scrobiculatum D.E. Stuntz"
251
- canonical("Arthopyrenia hyalospora (Banker) D. Hall X Hydnellum scrobiculatum D.E. Stuntz").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
252
50
 
253
- parse("Arthopyrenia hyalospora x").should_not be_nil
254
- value("Arthopyrenia hyalospora X").should == "Arthopyrenia hyalospora \303\227 ?"
255
- canonical("Arthopyrenia hyalospora x").should == "Arthopyrenia hyalospora"
256
- details("Arthopyrenia hyalospora x").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>"?"}}
257
- parse("Arthopyrenia hyalospora × ?").should_not be_nil
258
- details("Arthopyrenia hyalospora × ?").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>"?"}}
259
- end
260
-
261
-
262
-
263
- it "should parse name with subspecies without rank NOT BOTANICAL" do
264
- name = "Hydnellum scrobiculatum zonatum (Banker) D. Hall & D.E. Stuntz 1972"
265
- parse(name).should_not be_nil
266
- value(name).should == "Hydnellum scrobiculatum zonatum (Banker) D. Hall et D.E. Stuntz 1972"
267
- canonical(name).should == "Hydnellum scrobiculatum zonatum"
268
- details(name).should == {:orig_authors=>{:names=>["Banker"]}, :subspecies=>{:rank=>"n/a", :value=>"zonatum"}, :species=>"scrobiculatum", :authors=>{:year=>"1972", :names=>["D. Hall", "D.E. Stuntz"]}, :genus=>"Hydnellum"}
269
- sp = "Begonia pingbienensis angustior"
270
- parse(sp).should_not be_nil
271
- details(sp).should == {:genus=>"Begonia", :species=>"pingbienensis", :subspecies=>{:rank=>"n/a", :value=>"angustior"}}
272
- end
273
-
274
- it "should not parse utf-8 chars in name part" do
275
- parse("Érematosphaeria phaespora").should be_nil
276
- parse("Trematosphaeria phaeáapora").should be_nil
277
- end
278
-
279
- it "should parse some invalid names" do
280
- parse("Acarospora cratericola 1929").should_not be_nil
281
- parse("Agaricus acris var. (b.)").should_not be_nil
282
- value("Agaricus acris var. (b.)").should == "Agaricus acris var. (b.)"
283
- parse("Agaricus acris var. (b.)").should_not be_nil
284
- value("Agaricus acris var. (b.&c.)").should == "Agaricus acris var. (b.c.)"
285
- details("Agaricus acris var. (b.&c.)").should == {:editorial_markup=>"(b.c.)", :subspecies=>[{:rank=>"var.", :value=>nil}], :species=>"acris", :genus=>"Agaricus", :is_valid=>false}
286
-
287
- end
288
-
289
- end
51
+ end
@@ -0,0 +1,43 @@
1
+ dir = File.dirname("__FILE__")
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'treetop'
5
+ require 'yaml'
6
+
7
+ Treetop.load(File.expand_path(dir + '../../lib/biodiversity/parser/scientific_name_clean'))
8
+ Treetop.load(File.expand_path(dir + '../../lib/biodiversity/parser/scientific_name_dirty'))
9
+ Treetop.load(File.expand_path(dir + '../../lib/biodiversity/parser/scientific_name_canonical'))
10
+
11
+
12
+ describe ScientificNameCanonical do
13
+ before(:all) do
14
+ @parser = ScientificNameCanonicalParser.new
15
+ end
16
+
17
+ def parse(input)
18
+ @parser.parse(input)
19
+ end
20
+
21
+ def value(input)
22
+ parse(input).value
23
+ end
24
+
25
+ def canonical(input)
26
+ parse(input).canonical
27
+ end
28
+
29
+ def details(input)
30
+ parse(input).details
31
+ end
32
+
33
+ it 'should parse names with valid name part and unparseable rest' do
34
+ [
35
+ ['Moraea spathulata ( (L. f. Klatt','Moraea spathulata',{:genus=>"Moraea", :species=>"spathulata", :name_part_verbatim=>"Moraea spathulata", :auth_part_verbatim=>"( (L. f. Klatt"} ],
36
+ ['Verpericola megasoma ""Dall" Pils.','Verpericola megasoma',{:genus=>"Verpericola", :species=>"megasoma", :name_part_verbatim=>"Verpericola megasoma", :auth_part_verbatim=>"\"\"Dall\" Pils."}]
37
+ ].each do |n|
38
+ parse(n[0]).should_not be_nil
39
+ value(n[0]).should == n[1]
40
+ details(n[0]).should == n[2]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,393 @@
1
+ # encoding: UTF-8
2
+ dir = File.dirname("__FILE__")
3
+ require 'rubygems'
4
+ require 'spec'
5
+ require 'treetop'
6
+
7
+ Treetop.load(File.expand_path(dir + '../../lib/biodiversity/parser/scientific_name_clean'))
8
+
9
+ describe ScientificNameClean do
10
+ before(:all) do
11
+ @parser = ScientificNameCleanParser.new
12
+ end
13
+
14
+ def parse(input)
15
+ @parser.parse(input)
16
+ end
17
+
18
+ def value(input)
19
+ parse(input).value
20
+ end
21
+
22
+ def canonical(input)
23
+ parse(input).canonical
24
+ end
25
+
26
+ def details(input)
27
+ parse(input).details
28
+ end
29
+
30
+ it 'should parse uninomial' do
31
+ sn = 'Pseudocercospora'
32
+ parse(sn).should_not be_nil
33
+ value(sn).should == 'Pseudocercospora'
34
+ canonical(sn).should == 'Pseudocercospora'
35
+ details(sn).should == {:uninomial=>"Pseudocercospora"}
36
+ end
37
+
38
+ it 'should parse canonical' do
39
+ sn = 'Pseudocercospora dendrobii'
40
+ parse(sn).should_not be_nil
41
+ value(sn).should == 'Pseudocercospora dendrobii'
42
+ canonical(sn).should == 'Pseudocercospora dendrobii'
43
+ details(sn).should == {:species=>"dendrobii", :genus=>"Pseudocercospora"}
44
+ end
45
+
46
+ it 'should parse subgenus ZOOLOGICAL' do
47
+ sn = "Doriteuthis (Amerigo) pealeii Author 1999"
48
+ parse(sn).should_not be_nil
49
+ value(sn).should == "Doriteuthis (Amerigo) pealeii Author 1999"
50
+ canonical(sn).should == "Doriteuthis pealeii"
51
+ details(sn).should == {:genus=>"Doriteuthis", :subgenus=>"Amerigo", :species=>"pealeii", :authors=>{:names=>["Author"], :year=>"1999"}, :name_part_verbatim=>"Doriteuthis (Amerigo) pealeii", :auth_part_verbatim=>"Author 1999"}
52
+ end
53
+
54
+ it 'should parse æ in the name' do
55
+ names = [
56
+ ["Læptura laetifica Dow, 1913", "Laeptura laetifica Dow 1913"],
57
+ ["Leptura lætifica Dow, 1913", "Leptura laetifica Dow 1913"],
58
+ ["Leptura leætifica Dow, 1913", "Leptura leaetifica Dow 1913"],
59
+ ["Leæptura laetifica Dow, 1913", "Leaeptura laetifica Dow 1913"],
60
+ ["Leœptura laetifica Dow, 1913", "Leoeptura laetifica Dow 1913"],
61
+ ['Ærenea cognata Lacordaire, 1872', 'Ærenea cognata Lacordaire 1872'],
62
+ ['Œdicnemus capensis ehrenbergi', 'Œdicnemus capensis ehrenbergi'],
63
+ ['Œnanthe œnanthe œnanthe','Œnanthe oenanthe oenanthe']
64
+ ]
65
+ names.each do |name_pair|
66
+ parse(name_pair[0]).should_not be_nil
67
+ value(name_pair[0]).should == name_pair[1]
68
+ end
69
+ end
70
+
71
+ it 'should parse names with "common" utf-8 charactes' do
72
+ names = ["Rühlella","Sténométope laevissimus Bibron 1855"].each do |name|
73
+ parse(name).should_not be_nil
74
+ end
75
+ end
76
+
77
+ it 'should parse names with a valid 2 letter genus' do
78
+ ["Ca Dyar 1914",
79
+ "Ea Distant 1911",
80
+ "Ge Nicéville 1895",
81
+ "Ia Thomas 1902",
82
+ "Io Lea 1831",
83
+ "Io Blanchard 1852",
84
+ "Ix Bergroth 1916",
85
+ "Lo Seale 1906",
86
+ "Oa Girault 1929",
87
+ "Ra Whitley 1931",
88
+ "Ty Bory de St. Vincent 1827",
89
+ "Ua Girault 1929",
90
+ "Aa Baker 1940",
91
+ #"Mc",
92
+ "Ja Uéno 1955",
93
+ "Zu Walters & Fitch 1960",
94
+ "La Bleszynski 1966",
95
+ "Qu Durkoop",
96
+ "As Slipinski 1982",
97
+ "Ba Solem 1983"].each do |name|
98
+ parse(name).should_not be_nil
99
+ end
100
+ canonical('Quoyula').should == 'Quoyula'
101
+ end
102
+
103
+ it 'should parse year' do
104
+ sn = "Platypus bicaudatulus Schedl 1935"
105
+ parse(sn).should_not be_nil
106
+ value(sn).should == "Platypus bicaudatulus Schedl 1935"
107
+ sn = "Platypus bicaudatulus Schedl, 1935h"
108
+ parse(sn).should_not be_nil
109
+ value(sn).should == "Platypus bicaudatulus Schedl 1935"
110
+ details(sn).should == {:genus=>"Platypus", :species=>"bicaudatulus", :authors=>{:names=>["Schedl"], :year=>"1935"}, :name_part_verbatim=>"Platypus bicaudatulus", :auth_part_verbatim=>"Schedl, 1935h"}
111
+ parse("Platypus bicaudatulus Schedl, 1935B").should_not be_nil
112
+ end
113
+
114
+ it 'should parse species autonym for complex subspecies authorships' do
115
+ parse("Aus bus Linn. var. bus").should_not be_nil
116
+ details("Aus bus Linn. var. bus").should == {:genus=>"Aus", :species=>"bus", :subspecies=>[{:rank=>"var.", :value=>"bus"}], :species_authors=>{:authors=>{:names=>["Linn."]}}, :name_part_verbatim=>"Aus bus", :auth_part_verbatim=>"Linn. var. bus"}
117
+ parse("Agalinis purpurea (L.) Briton var. borealis (Berg.) Peterson 1987").should_not be_nil
118
+ details("Agalinis purpurea (L.) Briton var. borealis (Berg.) Peterson 1987").should == {:genus=>"Agalinis", :species=>"purpurea", :subspecies=>[{:rank=>"var.", :value=>"borealis"}], :species_authors=>{:orig_authors=>{:names=>["L."]}, :authors=>{:names=>["Briton"]}}, :subspecies_authors=>{:orig_authors=>{:names=>["Berg."]}, :authors=>{:names=>["Peterson"], :year=>"1987"}}, :name_part_verbatim=>"Agalinis purpurea", :auth_part_verbatim=>"(L.) Briton var. borealis (Berg.) Peterson 1987"}
119
+ end
120
+
121
+ it 'should parse several authors' do
122
+ sn = "Pseudocercospora dendrobii U. Braun & Crous"
123
+ parse(sn).should_not be_nil
124
+ value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
125
+ canonical(sn).should == "Pseudocercospora dendrobii"
126
+ details(sn).should == {:genus=>"Pseudocercospora", :species=>"dendrobii", :authors=>{:names=>["U. Braun", "Crous"]}, :name_part_verbatim=>"Pseudocercospora dendrobii", :auth_part_verbatim=>"U. Braun & Crous"}
127
+ sn = "Pseudocercospora dendrobii U. Braun and Crous"
128
+ parse(sn).should_not be_nil
129
+ value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
130
+ sn = "Pseudocercospora dendrobii U. Braun et Crous"
131
+ parse(sn).should_not be_nil
132
+ value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous"
133
+ end
134
+
135
+ it 'should parse several authors with a year' do
136
+ sn = "Pseudocercospora dendrobii U. Braun & Crous 2003"
137
+ parse(sn).should_not be_nil
138
+ value(sn).should == "Pseudocercospora dendrobii U. Braun et Crous 2003"
139
+ canonical(sn).should == "Pseudocercospora dendrobii"
140
+ details(sn).should == {:genus=>"Pseudocercospora", :species=>"dendrobii", :authors=>{:names=>["U. Braun", "Crous"], :year=>"2003"}, :name_part_verbatim=>"Pseudocercospora dendrobii", :auth_part_verbatim=>"U. Braun & Crous 2003"}
141
+ sn = "Pseudocercospora dendrobii Crous, 2003"
142
+ parse(sn).should_not be_nil
143
+ parse("Zophosis persis (Chatanay, 1914)").should_not be_nil
144
+ parse("Zophosis persis (Chatanay 1914)").should_not be_nil
145
+ parse("Zophosis persis (Chatanay), 1914").should_not be_nil
146
+ value("Zophosis persis (Chatanay), 1914").should == "Zophosis persis (Chatanay 1914)"
147
+ details("Zophosis persis (Chatanay), 1914").should == {:genus=>"Zophosis", :species=>"persis", :orig_authors=>{:names=>["Chatanay"]}, :year=>"1914", :name_part_verbatim=>"Zophosis persis", :auth_part_verbatim=>"(Chatanay), 1914"}
148
+
149
+ parse("Zophosis persis (Chatanay) 1914").should_not be_nil
150
+ #parse("Zophosis persis Chatanay (1914)").should_not be_nil
151
+ end
152
+
153
+ it 'should parse scientific name' do
154
+ parse("Pseudocercospora dendrobii (H.C. Burnett) U. Braun & Crous 2003").should_not be_nil
155
+ value("Pseudocercospora dendrobii(H.C. Burnett)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii (H.C. Burnett) U. Braun et Crous 2003"
156
+ canonical("Pseudocercospora dendrobii(H.C. Burnett)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii"
157
+ {:orig_authors=>{:names=>["H.C. Burnett"]}, :species=>"dendrobii", :authors=>{:year=>"2003", :names=>["U. Braun", "Crous"]}, :genus=>"Pseudocercospora"}
158
+
159
+ parse("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should_not be_nil
160
+ value("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should == "Stagonospora polyspora M.T. Lucas et Sousa da Câmara 1934"
161
+ details("Stagonospora polyspora M.T. Lucas & Sousa da Câmara 1934").should == {:genus=>"Stagonospora", :species=>"polyspora", :authors=>{:names=>["M.T. Lucas", "Sousa da Câmara"], :year=>"1934"}, :name_part_verbatim=>"Stagonospora polyspora", :auth_part_verbatim=>"M.T. Lucas & Sousa da Câmara 1934"}
162
+
163
+ parse("Cladoniicola staurospora Diederich, van den Boom & Aptroot 2001").should_not be_nil
164
+ parse("Yarrowia lipolytica var. lipolytica (Wick., Kurtzman & E.A. Herrm.) Van der Walt & Arx 1981").should_not be_nil
165
+ value("Yarrowia lipolytica var. lipolytica (Wick., Kurtzman & E.A. Herrm.) Van der Walt & Arx 1981").should == "Yarrowia lipolytica var. lipolytica (Wick., Kurtzman et E.A. Herrm.) Van der Walt et Arx 1981"
166
+ parse("Physalospora rubiginosa (Fr.) anon.").should_not be_nil
167
+ parse("Pleurotus ëous (Berk.) Sacc. 1887").should_not be_nil
168
+ parse("Lecanora wetmorei Śliwa 2004").should_not be_nil
169
+ # valid
170
+ # infraspecific
171
+ parse("Calicium furfuraceum * furfuraceum (L.) Pers. 1797").should_not be_nil
172
+ parse("Exobasidium vaccinii ** andromedae (P. Karst.) P. Karst. 1882").should_not be_nil
173
+ parse("Urceolaria scruposa **** clausa Flot. 1849").should_not be_nil
174
+ parse("Cortinarius angulatus B gracilescens Fr. 1838").should_not be_nil
175
+ parse("Cyathicula scelobelonium").should_not be_nil
176
+ # single quote that did not show
177
+ # parse("Phytophthora hedraiandra De Cock & Man in ?t Veld 2004"
178
+ # Phthora vastatrix d?Hérelle 1909
179
+ # author is exception
180
+ parse('Xylaria potentillae A S. Xu').should_not be_nil
181
+ parse("Tuber liui A S. Xu 1999").should_not be_nil
182
+ details("Tuber liui A S. Xu 1999").should == {:genus=>"Tuber", :species=>"liui", :authors=>{:names=>["A S. Xu"], :year=>"1999"}, :name_part_verbatim=>"Tuber liui", :auth_part_verbatim=>"A S. Xu 1999"}
183
+ parse('Xylaria potentillae A S. Xu').should_not be_nil
184
+ parse("Agaricus squamula Berk. & M.A. Curtis 1860").should_not be_nil
185
+ parse("Peltula coriacea Büdel, Henssen & Wessels 1986").should_not be_nil
186
+ #had to add no dot rule for trinomials without a rank to make it to work
187
+ parse("Saccharomyces drosophilae anon.").should_not be_nil
188
+ details("Saccharomyces drosophilae anon.").should == {:genus=>"Saccharomyces", :species=>"drosophilae", :authors=>{:names=>["anon."]}, :name_part_verbatim=>"Saccharomyces drosophilae", :auth_part_verbatim=>"anon."}
189
+ end
190
+
191
+ it 'should parse several authors with several years' do
192
+ parse("Pseudocercospora dendrobii (H.C. Burnett 1883) U. Braun & Crous 2003").should_not be_nil
193
+ value("Pseudocercospora dendrobii(H.C. Burnett1883)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii (H.C. Burnett 1883) U. Braun et Crous 2003"
194
+ canonical("Pseudocercospora dendrobii(H.C. Burnett 1883)U. Braun & Crous 2003").should == "Pseudocercospora dendrobii"
195
+ details("Pseudocercospora dendrobii(H.C. Burnett 1883)U. Braun & Crous 2003").should == {:genus=>"Pseudocercospora", :species=>"dendrobii", :orig_authors=>{:names=>["H.C. Burnett"], :year=>"1883"}, :authors=>{:names=>["U. Braun", "Crous"], :year=>"2003"}, :name_part_verbatim=>"Pseudocercospora dendrobii", :auth_part_verbatim=>"(H.C. Burnett 1883)U. Braun & Crous 2003"}
196
+ end
197
+
198
+ it 'should parse unknown original authors (auct.)/(hort.)/(?)' do
199
+ parse("Tragacantha leporina (?) Kuntze").should_not be_nil
200
+ value("Tragacantha leporina ( ? ) Kuntze").should == "Tragacantha leporina (?) Kuntze"
201
+ parse("Lachenalia tricolor var. nelsonii (auct.) Baker").should_not be_nil
202
+ value("Lachenalia tricolor var. nelsonii ( auct. ) Baker").should == "Lachenalia tricolor var. nelsonii (auct.) Baker"
203
+ details("Lachenalia tricolor var. nelsonii ( auct. ) Baker").should == {:genus=>"Lachenalia", :species=>"tricolor", :subspecies=>[{:rank=>"var.", :value=>"nelsonii"}], :orig_authors=>"unknown", :authors=>{:names=>["Baker"]}, :name_part_verbatim=>"Lachenalia tricolor var. nelsonii", :auth_part_verbatim=>"( auct. ) Baker"}
204
+ end
205
+
206
+ it 'should parse unknown authors auct./anon./hort./ht.' do
207
+ parse("Puya acris ht. ex Gentil").should_not be_nil
208
+ end
209
+
210
+
211
+ it 'should not parse serveral authors groups with several years NOT CORRECT' do
212
+ parse("Pseudocercospora dendrobii (H.C. Burnett 1883) (Leight.) (Movss. 1967) U. Braun & Crous 2003").should be_nil
213
+ end
214
+
215
+ it 'should parse names with taxon concept sec. part' do
216
+ parse("Sténométope laevissimus sec. Eschmeyer 2004").should_not be_nil
217
+ details('Sténométope laevissimus sec. Eschmeyer 2004').should == {:genus=>"Sténométope", :species=>"laevissimus", :taxon_concept=>{:authors=>{:names=>["Eschmeyer"], :year=>"2004"}}, :name_part_verbatim=>"Sténométope laevissimus", :auth_part_verbatim=>"sec. Eschmeyer 2004"}
218
+ parse("Sténométope laevissimus Bibron 1855 sec. Eschmeyer 2004").should_not be_nil
219
+ details('Sténométope laevissimus Bibron 1855 sec. Eschmeyer 2004').should == {:genus=>"Sténométope", :species=>"laevissimus", :authors=>{:names=>["Bibron"], :year=>"1855"}, :taxon_concept=>{:authors=>{:names=>["Eschmeyer"], :year=>"2004"}}, :name_part_verbatim=>"Sténométope laevissimus", :auth_part_verbatim=>"Bibron 1855 sec. Eschmeyer 2004"}
220
+ #
221
+ # puts "<pre>"
222
+ # puts @parser.failure_reason
223
+ # #puts @parser.public_methods.select{|r| r.match /fail/}
224
+ # puts "</pre>"
225
+ end
226
+
227
+
228
+ it 'should parse utf-8 name' do
229
+ parse("Trematosphaeria phaeospora (E. Müll.) L. Holm 1957").should_not be_nil
230
+ value("Trematosphaeria phaeospora ( E. Müll. )L. Holm 1957").should == "Trematosphaeria phaeospora (E. Müll.) L. Holm 1957"
231
+ canonical("Trematosphaeria phaeospora(E. Müll.) L. Holm 1957").should == "Trematosphaeria phaeospora"
232
+ details("Trematosphaeria phaeospora(E. Müll.) L. Holm 1957 ").should == {:genus=>"Trematosphaeria", :species=>"phaeospora", :orig_authors=>{:names=>["E. Müll."]}, :authors=>{:names=>["L. Holm"], :year=>"1957"}, :name_part_verbatim=>"Trematosphaeria phaeospora", :auth_part_verbatim=>"(E. Müll.) L. Holm 1957"}
233
+ end
234
+
235
+ it "should parse name with var." do
236
+ parse("Phaeographis inusta var. macularis (Leight.) A.L. Sm. 1861").should_not be_nil
237
+ value("Phaeographis inusta var. macularis(Leight.) A.L. Sm. 1861").should == "Phaeographis inusta var. macularis (Leight.) A.L. Sm. 1861"
238
+ canonical("Phaeographis inusta var. macularis(Leight.) A.L. Sm. 1861").should == "Phaeographis inusta macularis"
239
+ end
240
+
241
+ it "should parse name with morph." do
242
+ val = "Callideriphus flavicollis morph. reductus Fuchs 1961"
243
+ parse(val).should_not be_nil
244
+ value(val).should == "Callideriphus flavicollis morph. reductus Fuchs 1961"
245
+ canonical(val).should == "Callideriphus flavicollis reductus"
246
+ #details(val).should == {}
247
+ end
248
+
249
+ # "subsect."/"subtrib."/"subgen."/"trib."/
250
+ #Stipa Speg. subgen. Leptostipa
251
+ #Sporobolus subgen. Sporobolus R.Br.
252
+
253
+ # it 'should parse name with "subsect."/"subtrib."/"subgen."/"trib."' do
254
+ # val = "Sporobolus subgen. Sporobolus R.Br."
255
+ # parse(val).should_not be_nil
256
+ # # value(val).should == val
257
+ # # canonical(val).should == "Callideriphus flavicollis reductus"
258
+ # # details(val).should == {}
259
+ # end
260
+
261
+ it "should parse name with forma/fo./form./f." do
262
+ parse("Caulerpa cupressoides forma nuda").should_not be_nil
263
+ value("Caulerpa cupressoides forma nuda").should == "Caulerpa cupressoides f. nuda"
264
+ canonical("Caulerpa cupressoides forma nuda").should == "Caulerpa cupressoides nuda"
265
+ details("Caulerpa cupressoides forma nuda").should == {:genus=>"Caulerpa", :species=>"cupressoides", :subspecies=>[{:rank=>"f.", :value=>"nuda"}]}
266
+ parse("Chlorocyperus glaber form. fasciculariforme (Lojac.) Soó").should_not be_nil
267
+ value("Chlorocyperus glaber form. fasciculariforme (Lojac.) Soó").should == "Chlorocyperus glaber f. fasciculariforme (Lojac.) Soó"
268
+ canonical("Chlorocyperus glaber form. fasciculariforme (Lojac.) Soó").should == "Chlorocyperus glaber fasciculariforme"
269
+ details("Chlorocyperus glaber form. fasciculariforme (Lojac.) Soó").should == {:genus=>"Chlorocyperus", :species=>"glaber", :subspecies=>[{:rank=>"f.", :value=>"fasciculariforme"}], :orig_authors=>{:names=>["Lojac."]}, :authors=>{:names=>["Soó"]}, :name_part_verbatim=>"Chlorocyperus glaber form. fasciculariforme", :auth_part_verbatim=>"(Lojac.) Soó"}
270
+ parse("Bambusa nana Roxb. fo. alphonse-karri (Mitford ex Satow) Makino ex Shiros.").should_not be_nil
271
+ value("Bambusa nana Roxb. fo. alphonse-karri (Mitford ex Satow) Makino ex Shiros.").should == "Bambusa nana Roxb. f. alphonse-karri (Mitford ex Satow) Makino ex Shiros."
272
+ canonical("Bambusa nana Roxb. fo. alphonse-karri (Mitford ex Satow) Makino ex Shiros.").should == "Bambusa nana alphonse-karri"
273
+ details("Bambusa nana Roxb. fo. alphonse-karri (Mitford ex Satow) Makino ex Shiros.").should == {:genus=>"Bambusa", :species=>"nana", :subspecies=>[{:rank=>"f.", :value=>"alphonse-karri"}], :species_authors=>{:authors=>{:names=>["Roxb."]}}, :subspecies_authors=>{:original_revised_name_authors=>{:revised_authors=>{:names=>["Mitford"]}, :authors=>{:names=>["Satow"]}}, :revised_name_authors=>{:revised_authors=>{:names=>["Makino"]}, :authors=>{:names=>["Shiros."]}}}, :name_part_verbatim=>"Bambusa nana", :auth_part_verbatim=>"Roxb. fo. alphonse-karri (Mitford ex Satow) Makino ex Shiros."}
274
+ parse("Sphaerotheca fuliginea f. dahliae Movss. 1967").should_not be_nil
275
+ value(" Sphaerotheca fuliginea f. dahliae Movss. 1967 ").should == "Sphaerotheca fuliginea f. dahliae Movss. 1967"
276
+ canonical("Sphaerotheca fuliginea f. dahliae Movss. 1967").should == "Sphaerotheca fuliginea dahliae"
277
+ details("Sphaerotheca fuliginea f. dahliae Movss. 1967").should == {:genus=>"Sphaerotheca", :species=>"fuliginea", :subspecies=>[{:rank=>"f.", :value=>"dahliae"}], :authors=>{:names=>["Movss."], :year=>"1967"}, :name_part_verbatim=>"Sphaerotheca fuliginea f. dahliae", :auth_part_verbatim=>"Movss. 1967"}
278
+ end
279
+
280
+ it "should parse name with several subspecies names NOT BOTANICAL CODE BUT NOT INFREQUENT" do
281
+ parse("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should_not be_nil
282
+ value("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should == "Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall et D.E. Stuntz 1972"
283
+ details("Hydnellum scrobiculatum var. zonatum f. parvum (Banker) D. Hall & D.E. Stuntz 1972").should == {:genus=>"Hydnellum", :species=>"scrobiculatum", :subspecies=>[{:rank=>"var.", :value=>"zonatum"}, {:rank=>"f.", :value=>"parvum"}], :is_valid=>false, :orig_authors=>{:names=>["Banker"]}, :authors=>{:names=>["D. Hall", "D.E. Stuntz"], :year=>"1972"}, :name_part_verbatim=>"Hydnellum scrobiculatum var. zonatum f. parvum", :auth_part_verbatim=>"(Banker) D. Hall & D.E. Stuntz 1972"}
284
+ end
285
+
286
+ it "should parse status BOTANICAL RARE" do
287
+ #it is always latin abbrev often 2 words
288
+ parse("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should_not be_nil
289
+ value("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == "Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov."
290
+ canonical("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == "Arthopyrenia hyalospora"
291
+ details("Arthopyrenia hyalospora (Nyl.) R.C. Harris comb. nov.").should == {:genus=>"Arthopyrenia", :species=>"hyalospora", :orig_authors=>{:names=>["Nyl."]}, :authors=>{:names=>["R.C. Harris"]}, :status=>"comb. nov.", :name_part_verbatim=>"Arthopyrenia hyalospora", :auth_part_verbatim=>"(Nyl.) R.C. Harris comb. nov."}
292
+ end
293
+
294
+ it "should parse name without a year but with authors" do
295
+ parse("Arthopyrenia hyalospora (Nyl.) R.C. Harris").should_not be_nil
296
+ value("Arthopyrenia hyalospora(Nyl.)R.C. Harris").should == "Arthopyrenia hyalospora (Nyl.) R.C. Harris"
297
+ canonical("Arthopyrenia hyalospora (Nyl.) R.C. Harris").should == "Arthopyrenia hyalospora"
298
+ end
299
+
300
+ it "should parse revised (ex) names" do
301
+ #invalidly published
302
+ parse("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should_not be_nil
303
+ value("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == "Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris"
304
+ canonical("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == "Arthopyrenia hyalospora"
305
+ details("Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == {:genus=>"Arthopyrenia", :species=>"hyalospora", :original_revised_name_authors=>{:revised_authors=>{:names=>["Nyl."]}, :authors=>{:names=>["Banker"]}}, :authors=>{:names=>["R.C. Harris"]}, :name_part_verbatim=>"Arthopyrenia hyalospora", :auth_part_verbatim=>"(Nyl. ex Banker) R.C. Harris"}
306
+ parse("Arthopyrenia hyalospora Nyl. ex Banker").should_not be_nil
307
+
308
+ parse("Glomopsis lonicerae Peck ex C.J. Gould 1945").should_not be_nil
309
+ details("Glomopsis lonicerae Peck ex C.J. Gould 1945").should == {:genus=>"Glomopsis", :species=>"lonicerae", :revised_name_authors=>{:revised_authors=>{:names=>["Peck"]}, :authors=>{:names=>["C.J. Gould"], :year=>"1945"}}, :name_part_verbatim=>"Glomopsis lonicerae", :auth_part_verbatim=>"Peck ex C.J. Gould 1945"}
310
+
311
+ parse("Acanthobasidium delicatum (Wakef.) Oberw. ex Jülich 1979").should_not be_nil
312
+ parse("Mycosphaerella eryngii (Fr. ex Duby) Johanson ex Oudem. 1897").should_not be_nil
313
+ details("Mycosphaerella eryngii (Fr. ex Duby) Johanson ex Oudem. 1897").should == {:genus=>"Mycosphaerella", :species=>"eryngii", :original_revised_name_authors=>{:revised_authors=>{:names=>["Fr."]}, :authors=>{:names=>["Duby"]}}, :revised_name_authors=>{:revised_authors=>{:names=>["Johanson"]}, :authors=>{:names=>["Oudem."], :year=>"1897"}}, :name_part_verbatim=>"Mycosphaerella eryngii", :auth_part_verbatim=>"(Fr. ex Duby) Johanson ex Oudem. 1897"}
314
+ #invalid but happens
315
+ parse("Mycosphaerella eryngii (Fr. Duby) ex Oudem. 1897").should_not be_nil
316
+ parse("Mycosphaerella eryngii (Fr.ex Duby) ex Oudem. 1897").should_not be_nil
317
+ parse("Salmonella werahensis (Castellani) Hauduroy and Ehringer in Hauduroy 1937").should_not be_nil
318
+ end
319
+
320
+ it "should parse multiplication sign" do
321
+ parse("Arthopyrenia x hyalospora (Nyl.) R.C. Harris").should_not be_nil
322
+ details("Arthopyrenia x hyalospora (Nyl. ex Banker) R.C. Harris").should == {:genus=>"Arthopyrenia", :species=>"hyalospora", :cross=>"inside", :original_revised_name_authors=>{:revised_authors=>{:names=>["Nyl."]}, :authors=>{:names=>["Banker"]}}, :authors=>{:names=>["R.C. Harris"]}, :name_part_verbatim=>"Arthopyrenia x hyalospora", :auth_part_verbatim=>"(Nyl. ex Banker) R.C. Harris"}
323
+ parse("Arthopyrenia X hyalospora(Nyl. ex Banker) R.C. Harris").should_not be_nil
324
+ parse("x Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should_not be_nil
325
+ details("x Arthopyrenia hyalospora (Nyl. ex Banker) R.C. Harris").should == {:genus=>"Arthopyrenia", :species=>"hyalospora", :cross=>"before", :original_revised_name_authors=>{:revised_authors=>{:names=>["Nyl."]}, :authors=>{:names=>["Banker"]}}, :authors=>{:names=>["R.C. Harris"]}, :name_part_verbatim=>"x Arthopyrenia hyalospora", :auth_part_verbatim=>"(Nyl. ex Banker) R.C. Harris"}
326
+ parse("X Arthopyrenia (Nyl. ex Banker) R.C. Harris").should_not be_nil
327
+ details("X Arthopyrenia (Nyl. ex Banker) R.C. Harris").should == {:uninomial=>"Arthopyrenia", :cross=>"before", :original_revised_name_authors=>{:revised_authors=>{:names=>["Nyl."]}, :authors=>{:names=>["Banker"]}}, :authors=>{:names=>["R.C. Harris"]}, :name_part_verbatim=>"X Arthopyrenia", :auth_part_verbatim=>"(Nyl. ex Banker) R.C. Harris"}
328
+ #ascii for multiplication
329
+ parse("Melampsora × columbiana G. Newc. 2000").should_not be_nil
330
+ end
331
+
332
+ it "should parse hybrid combination" do
333
+ parse("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should_not be_nil
334
+ value("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
335
+ canonical("Arthopyrenia hyalospora X Hydnellum scrobiculatum").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
336
+ details("Arthopyrenia hyalospora x Hydnellum scrobiculatum").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>{:species=>"scrobiculatum", :genus=>"Hydnellum"}}}
337
+
338
+ parse("Arthopyrenia hyalospora (Banker) D. Hall x Hydnellum scrobiculatum D.E. Stuntz").should_not be_nil
339
+ value("Arthopyrenia hyalospora (Banker) D. Hall X Hydnellum scrobiculatum D.E. Stuntz").should == "Arthopyrenia hyalospora (Banker) D. Hall \303\227 Hydnellum scrobiculatum D.E. Stuntz"
340
+ canonical("Arthopyrenia hyalospora (Banker) D. Hall X Hydnellum scrobiculatum D.E. Stuntz").should == "Arthopyrenia hyalospora \303\227 Hydnellum scrobiculatum"
341
+
342
+ parse("Arthopyrenia hyalospora x").should_not be_nil
343
+ value("Arthopyrenia hyalospora X").should == "Arthopyrenia hyalospora \303\227 ?"
344
+ canonical("Arthopyrenia hyalospora x").should == "Arthopyrenia hyalospora"
345
+ details("Arthopyrenia hyalospora x").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>"?"}}
346
+ parse("Arthopyrenia hyalospora × ?").should_not be_nil
347
+ details("Arthopyrenia hyalospora × ?").should == {:hybrid=>{:scientific_name1=>{:species=>"hyalospora", :genus=>"Arthopyrenia"}, :scientific_name2=>"?"}}
348
+ end
349
+
350
+
351
+
352
+ it "should parse name with subspecies without rank NOT BOTANICAL" do
353
+ name = "Hydnellum scrobiculatum zonatum (Banker) D. Hall & D.E. Stuntz 1972"
354
+ parse(name).should_not be_nil
355
+ value(name).should == "Hydnellum scrobiculatum zonatum (Banker) D. Hall et D.E. Stuntz 1972"
356
+ canonical(name).should == "Hydnellum scrobiculatum zonatum"
357
+ details(name).should == {:genus=>"Hydnellum", :species=>"scrobiculatum", :subspecies=>{:rank=>"n/a", :value=>"zonatum"}, :orig_authors=>{:names=>["Banker"]}, :authors=>{:names=>["D. Hall", "D.E. Stuntz"], :year=>"1972"}, :name_part_verbatim=>"Hydnellum scrobiculatum zonatum", :auth_part_verbatim=>"(Banker) D. Hall & D.E. Stuntz 1972"}
358
+ sp = "Begonia pingbienensis angustior"
359
+ parse(sp).should_not be_nil
360
+ details(sp).should == {:genus=>"Begonia", :species=>"pingbienensis", :subspecies=>{:rank=>"n/a", :value=>"angustior"}}
361
+ end
362
+
363
+ it "should not parse utf-8 chars in name part" do
364
+ parse("Érematosphaeria phaespora").should be_nil
365
+ parse("Trematosphaeria phaeáapora").should be_nil
366
+ end
367
+
368
+ it "should parse some invalid names" do
369
+ parse("Acarospora cratericola 1929").should_not be_nil
370
+ parse("Agaricus acris var. (b.)").should_not be_nil
371
+ value("Agaricus acris var. (b.)").should == "Agaricus acris var. (b.)"
372
+ parse("Agaricus acris var. (b.)").should_not be_nil
373
+ value("Agaricus acris var. (b.&c.)").should == "Agaricus acris var. (b.c.)"
374
+ details("Agaricus acris var. (b.&c.)").should == {:editorial_markup=>"(b.c.)", :subspecies=>[{:rank=>"var.", :value=>nil}], :species=>"acris", :genus=>"Agaricus", :is_valid=>false}
375
+
376
+ end
377
+
378
+ it 'should parse double parenthesis' do
379
+ val = "Eichornia crassipes ( (Martius) ) Solms-Laub."
380
+ parse(val).should_not be_nil
381
+ value(val).should == "Eichornia crassipes (Martius) Solms-Laub."
382
+ details(val).should == {:genus=>"Eichornia", :species=>"crassipes", :orig_authors=>{:names=>["Martius"]}, :authors=>{:names=>["Solms-Laub."]}, :name_part_verbatim=>"Eichornia crassipes", :auth_part_verbatim=>"( (Martius) ) Solms-Laub."}
383
+ end
384
+
385
+ # val = "Ferganoconcha? oblonga"
386
+ it 'should parse genus?' do
387
+ val = "Ferganoconcha? oblonga"
388
+ parse(val).should_not be_nil
389
+ value(val).should == "Ferganoconcha oblonga"
390
+ details(val).should == {:genus=>"Ferganoconcha", :species=>"oblonga"}
391
+ end
392
+
393
+ end