nexus_parser 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/MIT-LICENSE +20 -0
- data/README +13 -0
- data/README.rdoc +17 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/lexer.rb +66 -0
- data/lib/nexus_file.rb +282 -0
- data/lib/parser.rb +334 -0
- data/lib/tokens.rb +269 -0
- data/tasks/nexus_parser_tasks.rake +4 -0
- data/test/MX_test_03.nex +234 -0
- data/test/test.nex +382 -0
- data/test/test_nexus_parser.rb +937 -0
- data/uninstall.rb +1 -0
- metadata +82 -0
@@ -0,0 +1,937 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ruby-debug'
|
4
|
+
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/nexus_file'))
|
6
|
+
|
7
|
+
class NexusParserTest < Test::Unit::TestCase
|
8
|
+
def test_truth
|
9
|
+
assert true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Test_NexusFile_Builder < Test::Unit::TestCase
|
14
|
+
def test_builder
|
15
|
+
b = NexusFile::Builder.new
|
16
|
+
assert foo = b.nexus_file
|
17
|
+
assert_equal [], foo.taxa
|
18
|
+
assert_equal [], foo.characters
|
19
|
+
assert_equal [], foo.codings
|
20
|
+
assert_equal [], foo.sets
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
class Test_Regex < Test::Unit::TestCase
|
26
|
+
def test_begin_taxa
|
27
|
+
txt = " aslkfja\n Begin taxa; BLorf end; "
|
28
|
+
@regexp = Regexp.new(/\s*(Begin\s*taxa\s*;)\s*/i)
|
29
|
+
assert txt =~ @regexp
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
class Test_Lexer < Test::Unit::TestCase
|
36
|
+
def test_lexer
|
37
|
+
lexer = NexusFile::Lexer.new("[ foo ] BEGIN taxa; BLORF end;")
|
38
|
+
assert lexer.pop(NexusFile::Tokens::LBracket)
|
39
|
+
assert id = lexer.pop(NexusFile::Tokens::ID)
|
40
|
+
assert_equal(id.value, "foo")
|
41
|
+
assert lexer.pop(NexusFile::Tokens::RBracket)
|
42
|
+
assert lexer.pop(NexusFile::Tokens::BeginBlk)
|
43
|
+
assert lexer.pop(NexusFile::Tokens::TaxaBlk)
|
44
|
+
assert foo = lexer.pop(NexusFile::Tokens::ID)
|
45
|
+
assert_equal("BLORF", foo.value) # truncating whitespace
|
46
|
+
assert lexer.pop(NexusFile::Tokens::BlkEnd)
|
47
|
+
|
48
|
+
lexer2 = NexusFile::Lexer.new("[ foo ] begin authors; BLORF end; [] () some crud here")
|
49
|
+
assert lexer2.pop(NexusFile::Tokens::LBracket)
|
50
|
+
assert id = lexer2.pop(NexusFile::Tokens::ID)
|
51
|
+
assert_equal(id.value, "foo")
|
52
|
+
assert lexer2.pop(NexusFile::Tokens::RBracket)
|
53
|
+
assert lexer2.pop(NexusFile::Tokens::BeginBlk)
|
54
|
+
assert lexer2.pop(NexusFile::Tokens::AuthorsBlk)
|
55
|
+
assert lexer2.pop(NexusFile::Tokens::LBracket)
|
56
|
+
assert lexer2.pop(NexusFile::Tokens::RBracket)
|
57
|
+
assert lexer2.pop(NexusFile::Tokens::LParen)
|
58
|
+
assert lexer2.pop(NexusFile::Tokens::RParen)
|
59
|
+
|
60
|
+
|
61
|
+
lexer3 = NexusFile::Lexer.new("[ foo ] Begin Characters; BLORF end; [] () some crud here")
|
62
|
+
assert lexer3.pop(NexusFile::Tokens::LBracket)
|
63
|
+
assert id = lexer3.pop(NexusFile::Tokens::ID)
|
64
|
+
assert_equal(id.value, "foo")
|
65
|
+
assert lexer3.pop(NexusFile::Tokens::RBracket)
|
66
|
+
assert lexer3.pop(NexusFile::Tokens::BeginBlk)
|
67
|
+
assert lexer3.pop(NexusFile::Tokens::ChrsBlk)
|
68
|
+
assert foo = lexer3.pop(NexusFile::Tokens::ID)
|
69
|
+
assert_equal("BLORF", foo.value)
|
70
|
+
assert lexer3.pop(NexusFile::Tokens::BlkEnd)
|
71
|
+
|
72
|
+
lexer4 = NexusFile::Lexer.new("Begin Characters; 123123123 end; [] () some crud here")
|
73
|
+
assert lexer4.pop(NexusFile::Tokens::BeginBlk)
|
74
|
+
assert lexer4.pop(NexusFile::Tokens::ChrsBlk)
|
75
|
+
assert foo = lexer4.pop(NexusFile::Tokens::Number)
|
76
|
+
assert_equal(123123123, foo.value)
|
77
|
+
assert lexer4.pop(NexusFile::Tokens::BlkEnd)
|
78
|
+
|
79
|
+
lexer5 = NexusFile::Lexer.new("(0,1)")
|
80
|
+
assert lexer5.pop(NexusFile::Tokens::LParen)
|
81
|
+
assert foo = lexer5.pop(NexusFile::Tokens::Number)
|
82
|
+
assert_equal(0, foo.value)
|
83
|
+
assert lexer5.pop(NexusFile::Tokens::Comma)
|
84
|
+
assert foo = lexer5.pop(NexusFile::Tokens::Number)
|
85
|
+
assert_equal(1, foo.value)
|
86
|
+
assert lexer5.pop(NexusFile::Tokens::RParen)
|
87
|
+
|
88
|
+
lexer6 = NexusFile::Lexer.new(" 210(0,1)10A1\n")
|
89
|
+
assert foo = lexer6.pop(NexusFile::Tokens::RowVec)
|
90
|
+
assert_equal(["2","1","0",["0","1"],"1","0","A","1"], foo.value)
|
91
|
+
|
92
|
+
lexer6a = NexusFile::Lexer.new(" 21a(0 1)0b{3 4 5}(0)(1 a)\n")
|
93
|
+
assert foo = lexer6a.pop(NexusFile::Tokens::RowVec)
|
94
|
+
assert_equal(["2", "1", "a", ["0", "1"], "0", "b", ["3", "4", "5"], "0", ["1", "a"]], foo.value)
|
95
|
+
|
96
|
+
lexer6b = NexusFile::Lexer.new(" 201{0 1}{0 1}0100)\x0A") # *nix line ending
|
97
|
+
assert foo = lexer6b.pop(NexusFile::Tokens::RowVec)
|
98
|
+
assert_equal(["2", "0", "1", ["0", "1"], ["0", "1"], "0", "1", "0", "0"], foo.value)
|
99
|
+
|
100
|
+
lexer6c = NexusFile::Lexer.new(" 201{0 1}{0 1}0100)\x0D\x0A") # * dos line ending
|
101
|
+
assert foo = lexer6c.pop(NexusFile::Tokens::RowVec)
|
102
|
+
assert_equal(["2", "0", "1", ["0", "1"], ["0", "1"], "0", "1", "0", "0"], foo.value)
|
103
|
+
|
104
|
+
|
105
|
+
lexer7 = NexusFile::Lexer.new("read nothing till Nexus, not that nexus 13243 Block [] ();, this one: #nexus FOO")
|
106
|
+
assert foo = lexer7.pop(NexusFile::Tokens::NexusStart)
|
107
|
+
assert_equal('#nexus', foo.value)
|
108
|
+
|
109
|
+
|
110
|
+
## we strip comments before parsing now
|
111
|
+
# lexer8 = NexusFile::Lexer.new("[ foo ] Begin Characters; BLORF end; [] () some crud here")
|
112
|
+
# assert foo = lexer8.pop(NexusFile::Tokens::NexusComment)
|
113
|
+
# assert_equal "foo", foo.value
|
114
|
+
|
115
|
+
# assert lexer.pop(NexusFile::Tokens::Colon)
|
116
|
+
# assert num = lexer.pop(NexusFile::Tokens::Number)
|
117
|
+
# assert_equal(num.value, 0.0)
|
118
|
+
# assert lexer.pop(NexusFile::Tokens::Comma)
|
119
|
+
# assert lexer.pop(NexusFile::Tokens::SemiColon)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_row_vec
|
123
|
+
lexer = NexusFile::Lexer.new("0?(0 1)10(A BD , C)1(0,1,2)1-\n")
|
124
|
+
assert foo = lexer.pop(NexusFile::Tokens::RowVec)
|
125
|
+
assert_equal(["0", "?", ["0", "1"], "1", "0", ["A", "BD", "C"], "1", ["0", "1", "2"], "1", "-"], foo.value)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_punctuation
|
129
|
+
lexer = NexusFile::Lexer.new(',/=](\'NOT23\'[);,')
|
130
|
+
assert lexer.peek(NexusFile::Tokens::Comma)
|
131
|
+
assert lexer.pop(NexusFile::Tokens::Comma)
|
132
|
+
assert lexer.pop(NexusFile::Tokens::BckSlash)
|
133
|
+
assert lexer.pop(NexusFile::Tokens::Equals)
|
134
|
+
assert lexer.pop(NexusFile::Tokens::RBracket)
|
135
|
+
assert lexer.pop(NexusFile::Tokens::LParen)
|
136
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
137
|
+
assert_equal "NOT23", foo.value
|
138
|
+
assert lexer.pop(NexusFile::Tokens::LBracket)
|
139
|
+
assert lexer.pop(NexusFile::Tokens::RParen)
|
140
|
+
assert lexer.pop(NexusFile::Tokens::SemiColon)
|
141
|
+
assert lexer.pop(NexusFile::Tokens::Comma)
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_tax_labels
|
146
|
+
lexer = NexusFile::Lexer.new("Taxlabels 'foo' bar blorf \"stuff things\" stuff 'and foo';")
|
147
|
+
assert foo = lexer.pop(NexusFile::Tokens::Taxlabels)
|
148
|
+
assert_equal("Taxlabels ", foo.value)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_EndBlk
|
152
|
+
lexer = NexusFile::Lexer.new(" \n\n End ;")
|
153
|
+
assert foo = lexer.pop(NexusFile::Tokens::EndBlk)
|
154
|
+
lexer = NexusFile::Lexer.new("\n\nEnd;")
|
155
|
+
assert foo = lexer.pop(NexusFile::Tokens::EndBlk)
|
156
|
+
|
157
|
+
lexer = NexusFile::Lexer.new("123123 \n\nEnd;")
|
158
|
+
assert !lexer.peek(NexusFile::Tokens::EndBlk)
|
159
|
+
lexer = NexusFile::Lexer.new("this is not an \"end\"\n\nEnd;")
|
160
|
+
assert !lexer.peek(NexusFile::Tokens::EndBlk)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_semicolon
|
164
|
+
lexer = NexusFile::Lexer.new("; Matrix foo")
|
165
|
+
assert lexer.peek(NexusFile::Tokens::SemiColon)
|
166
|
+
assert foo = lexer.pop(NexusFile::Tokens::SemiColon)
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_label
|
170
|
+
lexer = NexusFile::Lexer.new(' \'foo\' bar, blorf; "stuff things" stuff \'and foo\' 23434 ""asdf"" \'Foo_And_Stuff\' ')
|
171
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
172
|
+
assert_equal "foo", foo.value
|
173
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
174
|
+
assert_equal "bar", foo.value
|
175
|
+
assert lexer.pop(NexusFile::Tokens::Comma)
|
176
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
177
|
+
assert_equal "blorf", foo.value
|
178
|
+
assert lexer.pop(NexusFile::Tokens::SemiColon)
|
179
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
180
|
+
assert_equal "stuff things", foo.value
|
181
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
182
|
+
assert_equal "stuff", foo.value
|
183
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
184
|
+
assert_equal "and foo", foo.value
|
185
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
186
|
+
assert_equal "23434", foo.value
|
187
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
188
|
+
assert_equal '"asdf"', foo.value
|
189
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
190
|
+
assert_equal 'Foo_And_Stuff', foo.value
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_odd_labels
|
194
|
+
lexer = NexusFile::Lexer.new("blorf 'fan shaped, narrow base and broad tip (Selkirkiella, Kochiura)' \"\"\" foo \"\"\" '''rupununi''' '''tanzania''' '''cup-shaped''' bar blorf\n;")
|
195
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
196
|
+
assert_equal "blorf", foo.value
|
197
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
198
|
+
assert_equal "fan shaped, narrow base and broad tip (Selkirkiella, Kochiura)", foo.value
|
199
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
200
|
+
assert_equal '"" foo ""', foo.value
|
201
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
202
|
+
assert_equal "''rupununi''", foo.value
|
203
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
204
|
+
assert_equal "''tanzania''", foo.value
|
205
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
206
|
+
assert_equal "''cup-shaped''", foo.value
|
207
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
208
|
+
assert_equal "bar", foo.value
|
209
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
210
|
+
assert_equal "blorf", foo.value
|
211
|
+
assert foo = lexer.pop(NexusFile::Tokens::SemiColon)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_title
|
215
|
+
lexer = NexusFile::Lexer.new( "TITLE 'Scharff&Coddington_1997_Araneidae';")
|
216
|
+
assert foo = lexer.pop(NexusFile::Tokens::Title)
|
217
|
+
assert_equal "TITLE 'Scharff&Coddington_1997_Araneidae';", foo.value
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
def test_dimensions
|
222
|
+
input = " DIMENSIONS NCHAR= 10"
|
223
|
+
lexer = NexusFile::Lexer.new(input)
|
224
|
+
assert foo = lexer.pop(NexusFile::Tokens::Dimensions)
|
225
|
+
assert_equal "DIMENSIONS", foo.value
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_format
|
229
|
+
input = " format NCHAR= 10"
|
230
|
+
lexer = NexusFile::Lexer.new(input)
|
231
|
+
assert foo = lexer.pop(NexusFile::Tokens::Format)
|
232
|
+
assert_equal "format", foo.value
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_odd_value_pair
|
236
|
+
lexer = NexusFile::Lexer.new(" TEXT CHARACTER = 3 TEXT = A62.003;
|
237
|
+
|
238
|
+
TEXT CHARACTER = 4 TEXT = A62.004; \n end; ")
|
239
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
240
|
+
assert foo = lexer.pop(NexusFile::Tokens::ValuePair)
|
241
|
+
blorf = {:character => "3"}
|
242
|
+
assert_equal blorf , foo.value
|
243
|
+
assert foo = lexer.pop(NexusFile::Tokens::ValuePair)
|
244
|
+
blorf = {:text => "A62.003"}
|
245
|
+
assert_equal blorf , foo.value
|
246
|
+
assert foo = lexer.pop(NexusFile::Tokens::Label)
|
247
|
+
assert_equal "TEXT", foo.value
|
248
|
+
assert foo = lexer.pop(NexusFile::Tokens::ValuePair)
|
249
|
+
blorf = {:character => "4"}
|
250
|
+
assert_equal blorf , foo.value
|
251
|
+
assert foo = lexer.pop(NexusFile::Tokens::ValuePair)
|
252
|
+
blorf = {:text => "A62.004"}
|
253
|
+
assert_equal blorf , foo.value
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
def test_value_pair
|
259
|
+
|
260
|
+
lexer0 = NexusFile::Lexer.new(' DATATYPE=STANDARD ')
|
261
|
+
assert foo = lexer0.pop(NexusFile::Tokens::ValuePair)
|
262
|
+
blorf = {:datatype => "STANDARD"}
|
263
|
+
assert_equal blorf , foo.value
|
264
|
+
|
265
|
+
lexer = NexusFile::Lexer.new(' DATATYPE = STANDARD ')
|
266
|
+
assert foo = lexer.pop(NexusFile::Tokens::ValuePair)
|
267
|
+
blorf = {:datatype => "STANDARD"}
|
268
|
+
assert_equal blorf , foo.value
|
269
|
+
|
270
|
+
lexer2 = NexusFile::Lexer.new(' DATATYPE ="STANDARD" ')
|
271
|
+
assert foo = lexer2.pop(NexusFile::Tokens::ValuePair)
|
272
|
+
assert_equal blorf, foo.value
|
273
|
+
|
274
|
+
lexer3 = NexusFile::Lexer.new('DATATYPE= "STANDARD" ')
|
275
|
+
assert foo = lexer3.pop(NexusFile::Tokens::ValuePair)
|
276
|
+
assert_equal blorf, foo.value
|
277
|
+
|
278
|
+
input= " NCHAR=10 ntaxa =10 nfoo='999' nbar = \" a b c \" ; "
|
279
|
+
lexer4 = NexusFile::Lexer.new(input)
|
280
|
+
assert foo = lexer4.pop(NexusFile::Tokens::ValuePair)
|
281
|
+
smorf = {:nchar => '10'}
|
282
|
+
assert_equal smorf, foo.value
|
283
|
+
assert foo = lexer4.pop(NexusFile::Tokens::ValuePair)
|
284
|
+
smorf = {:ntaxa => '10'}
|
285
|
+
assert_equal smorf, foo.value
|
286
|
+
assert foo = lexer4.pop(NexusFile::Tokens::ValuePair)
|
287
|
+
smorf = {:nfoo => '999'}
|
288
|
+
assert_equal smorf, foo.value
|
289
|
+
assert foo = lexer4.pop(NexusFile::Tokens::ValuePair)
|
290
|
+
smorf = {:nbar => 'a b c'}
|
291
|
+
assert_equal smorf, foo.value
|
292
|
+
|
293
|
+
lexer5 = NexusFile::Lexer.new(' symbols= " a c b d 1 " ')
|
294
|
+
assert foo = lexer5.pop(NexusFile::Tokens::ValuePair)
|
295
|
+
smorf = {:symbols => 'a c b d 1'}
|
296
|
+
assert_equal smorf, foo.value
|
297
|
+
|
298
|
+
lexer6 = NexusFile::Lexer.new(' missing = - ')
|
299
|
+
assert foo = lexer6.pop(NexusFile::Tokens::ValuePair)
|
300
|
+
smorf = {:missing => '-'}
|
301
|
+
assert_equal smorf, foo.value
|
302
|
+
|
303
|
+
lexer6a = NexusFile::Lexer.new("ntaxa=1;\n")
|
304
|
+
assert foo = lexer6a.pop(NexusFile::Tokens::ValuePair)
|
305
|
+
smorf = {:ntaxa => '1'}
|
306
|
+
assert_equal smorf, foo.value
|
307
|
+
|
308
|
+
lexer7 = NexusFile::Lexer.new("ntaxa =1;\n")
|
309
|
+
assert foo = lexer7.pop(NexusFile::Tokens::ValuePair)
|
310
|
+
smorf = {:ntaxa => '1'}
|
311
|
+
assert_equal smorf, foo.value
|
312
|
+
|
313
|
+
lexer8 = NexusFile::Lexer.new(" ntaxa = 1 ;\n")
|
314
|
+
assert foo = lexer8.pop(NexusFile::Tokens::ValuePair)
|
315
|
+
smorf = {:ntaxa => '1'}
|
316
|
+
assert_equal smorf, foo.value
|
317
|
+
|
318
|
+
lexer9 = NexusFile::Lexer.new(" TF = (CM 'This is an annotation that haa a hard return in it^n^n^n^nSo there!') ")
|
319
|
+
assert foo = lexer9.pop(NexusFile::Tokens::ValuePair)
|
320
|
+
smorf = {:tf => "(CM 'This is an annotation that haa a hard return in it^n^n^n^nSo there!')" }
|
321
|
+
assert_equal smorf, foo.value
|
322
|
+
|
323
|
+
lexer10 = NexusFile::Lexer.new(" TF = (CM 'This is an value pair that has (parens) within the value, twice! ()') ; some stuff left here ")
|
324
|
+
assert foo = lexer10.pop(NexusFile::Tokens::ValuePair)
|
325
|
+
smorf = {:tf => "(CM 'This is an value pair that has (parens) within the value, twice! ()')" }
|
326
|
+
assert_equal smorf, foo.value
|
327
|
+
|
328
|
+
lexer11 = NexusFile::Lexer.new("CHARACTER = 1 TEXT = A62.001;")
|
329
|
+
assert_equal true, !lexer11.peek(NexusFile::Tokens::SemiColon)
|
330
|
+
assert_equal true, lexer11.peek(NexusFile::Tokens::ValuePair)
|
331
|
+
assert foo = lexer11.pop(NexusFile::Tokens::ValuePair)
|
332
|
+
smorf = {:character => "1" }
|
333
|
+
assert_equal smorf, foo.value
|
334
|
+
assert foo = lexer11.pop(NexusFile::Tokens::ValuePair)
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_MesquiteIDs
|
338
|
+
lexer = NexusFile::Lexer.new('IDS JC1191fcddc3b425 JC1191fcddc3b426 JC1191fcddc3b427 JC1191fcddc3b428 JC1191fcddc3b429 JC1191fcddc3b430 JC1191fcddc3b431 JC1191fcddc3b432 JC1191fcddc3b433 JC1191fcddc3b434 ;
|
339
|
+
BLOCKID JC1191fcddc0c0;')
|
340
|
+
assert lexer.pop(NexusFile::Tokens::MesquiteIDs)
|
341
|
+
assert lexer.pop(NexusFile::Tokens::MesquiteBlockID)
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_TreesBlk
|
345
|
+
lexer = NexusFile::Lexer.new("BEGIN TREES;
|
346
|
+
Title Imported_trees;
|
347
|
+
LINK Taxa = 'Scharff&Coddington_1997_Araneidae';
|
348
|
+
TRANSLATE
|
349
|
+
1 Dictyna,
|
350
|
+
2 Uloborus,
|
351
|
+
3 Deinopis,
|
352
|
+
4 Nephila&Herennia,
|
353
|
+
5 'Nephilengys_cruentata',
|
354
|
+
6 Meta,
|
355
|
+
7 Leucauge_venusta,
|
356
|
+
8 Pachygnatha,
|
357
|
+
9 'Theridiosoma_01',
|
358
|
+
10 Tetragnatha;
|
359
|
+
TREE 'Imported tree 1+' = (1,((2,3),(((4,5),(6,(7,(8,10)))),9)));
|
360
|
+
TREE 'Imported tree 2+' = (1,((2,3),(((4,5),(6,(7,(8,10)))),9)));
|
361
|
+
TREE 'Imported tree 3+' = (1,((2,3),(((6,(4,5)),(7,(8,10))),9)));
|
362
|
+
TREE 'Imported tree 4+' = (1,((2,3),(((4,5),(6,(7,(8,10)))),9)));
|
363
|
+
TREE 'Imported tree 5+' = (1,((2,3),(((6,(4,5)),(7,(8,10))),9)));
|
364
|
+
TREE 'Imported tree 6+' = (1,((2,3),(((4,5),(6,(7,(8,10)))),9)));
|
365
|
+
TREE 'Imported tree 7+' = (1,((2,3),(((6,(4,5)),(7,(8,10))),9)));
|
366
|
+
TREE 'Imported tree 8+' = (1,((2,3),(((6,(4,5)),(7,(8,10))),9)));
|
367
|
+
|
368
|
+
END;
|
369
|
+
|
370
|
+
|
371
|
+
BEGIN LABELS;
|
372
|
+
CHARGROUPLABEL MM_Genitalia COLOR = (RGB 1.0 0.4 0.4) ;
|
373
|
+
CHARGROUPLABEL Somatic COLOR = (RGB 0.6 1.0 0.33333333) ;
|
374
|
+
CHARGROUPLABEL Spinnerets COLOR = (RGB 0.46666667 0.57254902 1.0) ;
|
375
|
+
CHARGROUPLABEL Behavior COLOR = (RGB 1.0 0.46666667 1.0) ;
|
376
|
+
|
377
|
+
|
378
|
+
END;")
|
379
|
+
|
380
|
+
assert lexer.pop(NexusFile::Tokens::BeginBlk)
|
381
|
+
assert foo = lexer.pop(NexusFile::Tokens::TreesBlk)
|
382
|
+
assert_equal 'TREES', foo.value.slice(0,5)
|
383
|
+
assert_equal 'END;', foo.value.slice(-4,4)
|
384
|
+
assert lexer.pop(NexusFile::Tokens::BeginBlk)
|
385
|
+
assert lexer.pop(NexusFile::Tokens::LabelsBlk)
|
386
|
+
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_NotesBlk
|
390
|
+
input = "BEGIN NOTES ;"
|
391
|
+
lexer = NexusFile::Lexer.new(input)
|
392
|
+
assert lexer.pop(NexusFile::Tokens::BeginBlk)
|
393
|
+
assert foo = lexer.pop(NexusFile::Tokens::NotesBlk)
|
394
|
+
assert "NOTES", foo.value
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_LabelsBlk
|
398
|
+
lexer = NexusFile::Lexer.new("
|
399
|
+
LABELS;
|
400
|
+
CHARGROUPLABEL MM_Genitalia COLOR = (RGB 1.0 0.4 0.4) ;
|
401
|
+
CHARGROUPLABEL Somatic COLOR = (RGB 0.6 1.0 0.33333333) ;
|
402
|
+
CHARGROUPLABEL Spinnerets COLOR = (RGB 0.46666667 0.57254902 1.0) ;
|
403
|
+
CHARGROUPLABEL Behavior COLOR = (RGB 1.0 0.46666667 1.0) ;
|
404
|
+
|
405
|
+
|
406
|
+
END;
|
407
|
+
|
408
|
+
BEGIN some other block;")
|
409
|
+
|
410
|
+
assert foo = lexer.pop(NexusFile::Tokens::LabelsBlk)
|
411
|
+
assert_equal 'LABELS', foo.value.slice(0,6)
|
412
|
+
assert_equal 'END;', foo.value.slice(-4,4)
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_SetsBlk
|
416
|
+
lexer = NexusFile::Lexer.new("
|
417
|
+
SETS;
|
418
|
+
CHARPARTITION * UNTITLED = Somatic : 1 - 2 4, MM_Genitalia : 5 - 8 10;
|
419
|
+
|
420
|
+
END;
|
421
|
+
BEGIN some other block;")
|
422
|
+
|
423
|
+
assert foo = lexer.pop(NexusFile::Tokens::SetsBlk)
|
424
|
+
assert_equal 'SETS', foo.value.slice(0,4)
|
425
|
+
assert_equal 'END;', foo.value.slice(-4,4)
|
426
|
+
end
|
427
|
+
|
428
|
+
|
429
|
+
|
430
|
+
def test_lexer_errors
|
431
|
+
lexer = NexusFile::Lexer.new("*&")
|
432
|
+
assert_raise(NexusFile::ParseError) {lexer.peek(NexusFile::Tokens::ID)}
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
|
437
|
+
class Test_Parser < Test::Unit::TestCase
|
438
|
+
def setup
|
439
|
+
# a Mesquite 2.n or higher file
|
440
|
+
@nf = File.read('MX_test_03.nex') # MX_test_01.nex
|
441
|
+
end
|
442
|
+
|
443
|
+
def teardown
|
444
|
+
@nf = nil
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_that_file_might_be_nexus
|
448
|
+
begin
|
449
|
+
assert !parse_nexus_file("#Nexblux Begin Natrix end;")
|
450
|
+
rescue NexusFile::ParseError
|
451
|
+
assert true
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_parse_initializes
|
456
|
+
foo = parse_nexus_file(@nf)
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_parse_file
|
460
|
+
# this is the major loop, all parts should exist
|
461
|
+
foo = parse_nexus_file(@nf)
|
462
|
+
|
463
|
+
assert_equal 10, foo.taxa.size
|
464
|
+
assert_equal 10, foo.characters.size
|
465
|
+
assert_equal 10, foo.codings.size
|
466
|
+
assert_equal 1, foo.taxa[1].notes.size # asserts that notes are parsing
|
467
|
+
assert_equal "norm", foo.characters[0].states["0"].name
|
468
|
+
assert_equal "modified", foo.characters[0].states["1"].name
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_parse_authors_blk
|
472
|
+
end
|
473
|
+
|
474
|
+
def test_taxa_block
|
475
|
+
# we've popped off the header already
|
476
|
+
input =
|
477
|
+
"TITLE 'Scharff&Coddington_1997_Araneidae';
|
478
|
+
DIMENSIONS NTAX=10;
|
479
|
+
TAXLABELS
|
480
|
+
Dictyna Uloborus Deinopis Nephila&Herennia 'Nephilengys_cruentata' Meta Leucauge_venusta Pachygnatha 'Theridiosoma_01' Tetragnatha
|
481
|
+
;
|
482
|
+
IDS JC1191fcddc2b128 JC1191fcddc2b129 JC1191fcddc2b130 JC1191fcddc2b131 JC1191fcddc2b132 JC1191fcddc2b133 JC1191fcddc2b134 JC1191fcddc2b135 JC1191fcddc2b137 JC1191fcddc2b136 ;
|
483
|
+
BLOCKID JC1191fcddc0c4;
|
484
|
+
END;"
|
485
|
+
|
486
|
+
builder = NexusFile::Builder.new
|
487
|
+
lexer = NexusFile::Lexer.new(input)
|
488
|
+
NexusFile::Parser.new(lexer,builder).parse_taxa_blk
|
489
|
+
foo = builder.nexus_file
|
490
|
+
|
491
|
+
assert_equal 10, foo.taxa.size
|
492
|
+
assert_equal "Dictyna", foo.taxa[0].name
|
493
|
+
assert_equal "Nephilengys_cruentata", foo.taxa[4].name
|
494
|
+
assert_equal "Theridiosoma_01", foo.taxa[8].name
|
495
|
+
assert_equal "Tetragnatha", foo.taxa[9].name
|
496
|
+
end
|
497
|
+
|
498
|
+
def test_taxa_block_without_IDS
|
499
|
+
# we've popped off the header already
|
500
|
+
input =
|
501
|
+
"TITLE 'Scharff&Coddington_1997_Araneidae';
|
502
|
+
DIMENSIONS NTAX=10;
|
503
|
+
TAXLABELS
|
504
|
+
Dictyna Uloborus Deinopis Nephila&Herennia 'Nephilengys_cruentata' Meta Leucauge_venusta Pachygnatha 'Theridiosoma_01' Tetragnatha
|
505
|
+
;
|
506
|
+
END;"
|
507
|
+
|
508
|
+
builder = NexusFile::Builder.new
|
509
|
+
lexer = NexusFile::Lexer.new(input)
|
510
|
+
NexusFile::Parser.new(lexer,builder).parse_taxa_blk
|
511
|
+
foo = builder.nexus_file
|
512
|
+
|
513
|
+
assert_equal 10, foo.taxa.size
|
514
|
+
assert_equal "Dictyna", foo.taxa[0].name
|
515
|
+
assert_equal "Nephilengys_cruentata", foo.taxa[4].name
|
516
|
+
assert_equal "Theridiosoma_01", foo.taxa[8].name
|
517
|
+
assert_equal "Tetragnatha", foo.taxa[9].name
|
518
|
+
end
|
519
|
+
|
520
|
+
|
521
|
+
|
522
|
+
def test_parse_characters_blk
|
523
|
+
input= "
|
524
|
+
TITLE 'Scharff&Coddington_1997_Araneidae';
|
525
|
+
DIMENSIONS NCHAR=10;
|
526
|
+
FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = \" 0 1 2 3 4 5 6 7 8 9 A\";
|
527
|
+
CHARSTATELABELS
|
528
|
+
1 Tibia_II / norm modified, 2 TII_macrosetae / '= TI' stronger, 3 Femoral_tuber / abs pres 'm-setae', 5 Cymbium / dorsal mesal lateral, 6 Paracymbium / abs pres, 7 Globular_tegulum / abs pres, 8 / entire w_lobe, 9 Conductor_wraps_embolus, 10 Median_apophysis / pres abs;
|
529
|
+
MATRIX
|
530
|
+
Dictyna 0?00201001
|
531
|
+
Uloborus 0?11000000
|
532
|
+
Deinopis 0?01002???
|
533
|
+
Nephila&Herennia 0?21010011
|
534
|
+
'Nephilengys_cruentata'0?(0,1)1010(0,1,2)11
|
535
|
+
Meta 0?01A10011
|
536
|
+
Leucauge_venusta ???--?-??-
|
537
|
+
Pachygnatha 0?210(0 1)0011
|
538
|
+
'Theridiosoma_01' ??????????
|
539
|
+
Tetragnatha 0?01011011
|
540
|
+
|
541
|
+
;
|
542
|
+
IDS JC1191fcddc3b425 JC1191fcddc3b426 JC1191fcddc3b427 JC1191fcddc3b428 JC1191fcddc3b429 JC1191fcddc3b430 JC1191fcddc3b431 JC1191fcddc3b432 JC1191fcddc3b433 JC1191fcddc3b434 ;
|
543
|
+
BLOCKID JC1191fcddc0c0;
|
544
|
+
|
545
|
+
END;"
|
546
|
+
|
547
|
+
builder = NexusFile::Builder.new
|
548
|
+
@lexer = NexusFile::Lexer.new(input)
|
549
|
+
|
550
|
+
# add the taxa, assumes we have them for comparison purposes, though we (shouldn't) ultimately need them
|
551
|
+
# foo.taxa = ["Dictyna", "Uloborus", "Deinopis", "Nephila&Herennia", "Nephilenygys_cruentata", "Meta", "Leucauge_venusta", "Pachygnatha", "Theridiosoma_01", "Tetragnatha"]
|
552
|
+
|
553
|
+
# stub the taxa, they would otherwise get added in dimensions or taxa block
|
554
|
+
(0..9).each{|i| builder.stub_taxon}
|
555
|
+
|
556
|
+
NexusFile::Parser.new(@lexer,builder).parse_characters_blk
|
557
|
+
foo = builder.nexus_file
|
558
|
+
|
559
|
+
assert_equal 10, foo.characters.size
|
560
|
+
assert_equal "Tibia_II", foo.characters[0].name
|
561
|
+
assert_equal "TII_macrosetae", foo.characters[1].name
|
562
|
+
|
563
|
+
assert_equal "norm", foo.characters[0].states["0"].name
|
564
|
+
assert_equal "modified", foo.characters[0].states["1"].name
|
565
|
+
|
566
|
+
|
567
|
+
# ?!!?
|
568
|
+
# foo.characters[0].states["1"].name
|
569
|
+
assert_equal ["", "abs", "pres"], foo.characters[9].states.keys.collect{|s| foo.characters[9].states[s].name}.sort
|
570
|
+
|
571
|
+
|
572
|
+
assert_equal ["0","1"], foo.codings[7][5].states
|
573
|
+
assert_equal ["?"], foo.codings[9][1].states
|
574
|
+
assert_equal ["-", "0", "1", "2", "A"], foo.characters[4].state_labels
|
575
|
+
end
|
576
|
+
|
577
|
+
def test_characters_block_without_IDs_or_title
|
578
|
+
input= "
|
579
|
+
DIMENSIONS NCHAR=10;
|
580
|
+
FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = \" 0 1 2 3 4 5 6 7 8 9 A\";
|
581
|
+
CHARSTATELABELS
|
582
|
+
1 Tibia_II / norm modified, 2 TII_macrosetae / '= TI' stronger, 3 Femoral_tuber / abs pres 'm-setae', 5 Cymbium / dorsal mesal lateral, 6 Paracymbium / abs pres, 7 Globular_tegulum / abs pres, 8 / entire w_lobe, 9 Conductor_wraps_embolus, 10 Median_apophysis / pres abs;
|
583
|
+
MATRIX
|
584
|
+
Dictyna 0?00201001
|
585
|
+
Uloborus 0?11000000
|
586
|
+
Deinopis 0?01002???
|
587
|
+
Nephila&Herennia 0?21010011
|
588
|
+
'Nephilengys_cruentata'0?(0,1)1010(0,1,2)11
|
589
|
+
Meta 0?01A10011
|
590
|
+
Leucauge_venusta ???--?-??-
|
591
|
+
Pachygnatha 0?210(0 1)0011
|
592
|
+
'Theridiosoma_01' ??????????
|
593
|
+
Tetragnatha 0?01011011
|
594
|
+
|
595
|
+
;
|
596
|
+
END;"
|
597
|
+
|
598
|
+
builder = NexusFile::Builder.new
|
599
|
+
@lexer = NexusFile::Lexer.new(input)
|
600
|
+
|
601
|
+
# add the taxa, assumes we have them for comparison purposes, though we (shouldn't) ultimately need them
|
602
|
+
# foo.taxa = ["Dictyna", "Uloborus", "Deinopis", "Nephila&Herennia", "Nephilenygys_cruentata", "Meta", "Leucauge_venusta", "Pachygnatha", "Theridiosoma_01", "Tetragnatha"]
|
603
|
+
|
604
|
+
# stub the taxa, they would otherwise get added in dimensions or taxa block
|
605
|
+
(0..9).each{|i| builder.stub_taxon}
|
606
|
+
|
607
|
+
NexusFile::Parser.new(@lexer,builder).parse_characters_blk
|
608
|
+
foo = builder.nexus_file
|
609
|
+
|
610
|
+
assert_equal 10, foo.characters.size
|
611
|
+
assert_equal "Tibia_II", foo.characters[0].name
|
612
|
+
assert_equal "TII_macrosetae", foo.characters[1].name
|
613
|
+
assert_equal "norm", foo.characters[0].states["0"].name
|
614
|
+
assert_equal "modified", foo.characters[0].states["1"].name
|
615
|
+
assert_equal ["", "abs", "pres"], foo.characters[9].states.keys.collect{|s| foo.characters[9].states[s].name}.sort
|
616
|
+
assert_equal ["0","1"], foo.codings[7][5].states
|
617
|
+
assert_equal ["?"], foo.codings[9][1].states
|
618
|
+
assert_equal ["-", "0", "1", "2", "A"], foo.characters[4].state_labels
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_characters_block_from_file
|
622
|
+
foo = parse_nexus_file(@nf)
|
623
|
+
assert 10, foo.characters.size
|
624
|
+
end
|
625
|
+
|
626
|
+
def test_codings
|
627
|
+
foo = parse_nexus_file(@nf)
|
628
|
+
assert 100, foo.codings.size # two multistates count in single cells
|
629
|
+
end
|
630
|
+
|
631
|
+
def test_parse_dimensions
|
632
|
+
input= " DIMENSIONS NCHAR=10 ntaxa =10 nfoo='999' nbar = \" a b c \" blorf=2; "
|
633
|
+
builder = NexusFile::Builder.new
|
634
|
+
lexer = NexusFile::Lexer.new(input)
|
635
|
+
|
636
|
+
NexusFile::Parser.new(lexer,builder).parse_dimensions
|
637
|
+
foo = builder.nexus_file
|
638
|
+
|
639
|
+
assert_equal "10", foo.vars[:nchar]
|
640
|
+
assert_equal "10", foo.vars[:ntaxa]
|
641
|
+
assert_equal "999", foo.vars[:nfoo]
|
642
|
+
assert_equal 'a b c', foo.vars[:nbar]
|
643
|
+
assert_equal '2', foo.vars[:blorf]
|
644
|
+
# add test that nothing is left in lexer
|
645
|
+
end
|
646
|
+
|
647
|
+
def test_parse_format
|
648
|
+
input = "FORMAT DATATYPE = STANDARD GAP = - MISSING = ? SYMBOLS = \" 0 1 2 3 4 5 6 7 8 9 A\";"
|
649
|
+
builder = NexusFile::Builder.new
|
650
|
+
lexer = NexusFile::Lexer.new(input)
|
651
|
+
|
652
|
+
NexusFile::Parser.new(lexer,builder).parse_format
|
653
|
+
foo = builder.nexus_file
|
654
|
+
|
655
|
+
assert_equal "STANDARD", foo.vars[:datatype]
|
656
|
+
assert_equal "-", foo.vars[:gap]
|
657
|
+
assert_equal "?", foo.vars[:missing]
|
658
|
+
assert_equal '0 1 2 3 4 5 6 7 8 9 A', foo.vars[:symbols]
|
659
|
+
# add test that nothing is left in lexer
|
660
|
+
end
|
661
|
+
|
662
|
+
def test_parse_chr_state_labels
|
663
|
+
input =" CHARSTATELABELS
|
664
|
+
1 Tibia_II / norm modified, 2 TII_macrosetae / '= TI' stronger, 3 Femoral_tuber / abs pres 'm-setae', 5 Cymbium / dorsal mesal lateral, 6 Paracymbium / abs pres, 7 Globular_tegulum / abs pres, 8 / entire w_lobe, 9 Conductor_wraps_embolus, 10 Median_apophysis / pres abs ;
|
665
|
+
MATRIX
|
666
|
+
fooo 01 more stuff here that should not be hit"
|
667
|
+
|
668
|
+
builder = NexusFile::Builder.new
|
669
|
+
lexer = NexusFile::Lexer.new(input)
|
670
|
+
|
671
|
+
(0..9).each{builder.stub_chr()}
|
672
|
+
|
673
|
+
NexusFile::Parser.new(lexer,builder).parse_chr_state_labels
|
674
|
+
|
675
|
+
foo = builder.nexus_file
|
676
|
+
assert_equal 10, foo.characters.size
|
677
|
+
assert_equal "Tibia_II", foo.characters[0].name
|
678
|
+
assert_equal "norm", foo.characters[0].states["0"].name
|
679
|
+
assert_equal "modified", foo.characters[0].states["1"].name
|
680
|
+
|
681
|
+
assert_equal "TII_macrosetae", foo.characters[1].name
|
682
|
+
assert_equal "= TI", foo.characters[1].states["0"].name
|
683
|
+
assert_equal "stronger", foo.characters[1].states["1"].name
|
684
|
+
|
685
|
+
assert_equal "Femoral_tuber", foo.characters[2].name
|
686
|
+
assert_equal "abs", foo.characters[2].states["0"].name
|
687
|
+
assert_equal "pres", foo.characters[2].states["1"].name
|
688
|
+
assert_equal "m-setae", foo.characters[2].states["2"].name
|
689
|
+
|
690
|
+
assert_equal "Undefined", foo.characters[3].name
|
691
|
+
assert_equal 0, foo.characters[3].states.keys.size
|
692
|
+
|
693
|
+
assert_equal "Cymbium", foo.characters[4].name
|
694
|
+
assert_equal "dorsal", foo.characters[4].states["0"].name
|
695
|
+
assert_equal "mesal", foo.characters[4].states["1"].name
|
696
|
+
assert_equal "lateral", foo.characters[4].states["2"].name
|
697
|
+
|
698
|
+
assert_equal "Paracymbium", foo.characters[5].name
|
699
|
+
assert_equal "abs", foo.characters[5].states["0"].name
|
700
|
+
assert_equal "pres", foo.characters[5].states["1"].name
|
701
|
+
|
702
|
+
assert_equal "Globular_tegulum", foo.characters[6].name
|
703
|
+
assert_equal "abs", foo.characters[6].states["0"].name
|
704
|
+
assert_equal "pres", foo.characters[6].states["1"].name
|
705
|
+
|
706
|
+
assert_equal "Undefined", foo.characters[7].name
|
707
|
+
assert_equal "entire", foo.characters[7].states["0"].name
|
708
|
+
assert_equal "w_lobe", foo.characters[7].states["1"].name
|
709
|
+
|
710
|
+
# ...
|
711
|
+
|
712
|
+
assert_equal "Median_apophysis", foo.characters[9].name
|
713
|
+
assert_equal "pres", foo.characters[9].states["0"].name
|
714
|
+
assert_equal "abs", foo.characters[9].states["1"].name
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_strange_chr_state_labels
|
718
|
+
input =" CHARSTATELABELS
|
719
|
+
29 'Metatarsal trichobothria (CodAra.29)' / 37623 '>2', 30 'Spinneret cuticle (CodAra.30)' / annulate ridged squamate;
|
720
|
+
Matrix
|
721
|
+
fooo 01 more stuff here that should not be hit"
|
722
|
+
|
723
|
+
builder = NexusFile::Builder.new
|
724
|
+
lexer = NexusFile::Lexer.new(input)
|
725
|
+
|
726
|
+
(0..29).each{builder.stub_chr()}
|
727
|
+
|
728
|
+
NexusFile::Parser.new(lexer,builder).parse_chr_state_labels
|
729
|
+
|
730
|
+
foo = builder.nexus_file
|
731
|
+
|
732
|
+
assert_equal "Metatarsal trichobothria (CodAra.29)", foo.characters[28].name
|
733
|
+
assert_equal "37623", foo.characters[28].states["0"].name
|
734
|
+
assert_equal ">2", foo.characters[28].states["1"].name
|
735
|
+
|
736
|
+
assert_equal "Spinneret cuticle (CodAra.30)", foo.characters[29].name
|
737
|
+
assert_equal "annulate", foo.characters[29].states["0"].name
|
738
|
+
assert_equal "ridged", foo.characters[29].states["1"].name
|
739
|
+
assert_equal "squamate", foo.characters[29].states["2"].name
|
740
|
+
|
741
|
+
end
|
742
|
+
|
743
|
+
def DONT_test_parse_really_long_string_of_chr_state_labels
|
744
|
+
input =" CHARSTATELABELS
|
745
|
+
1 Epigynal_ventral_margin / 'entire (Fig. 15G)' 'with scape (Fig. 27D)', 2 Epigynal_external_structure / openings_on_a_broad_depression 'copulatory openings on plate, flush with abdomen, sometimes slit like', 3 Epigynal_depression / 'round or square, at most slightly wider than high ' 'elongate, at least twice as wide as high ', 4 Epigynal_plate_surface / 'smooth (Fig. 12E)' 'ridged (Fig. 21G)', 5 epignynal_septum / absent_ present_, 6 Copulatory_bursa_anterior_margin / 'entire, broadly transverse (Fig. 19B)' 'medially acute (Figs. 22G, 40B)', 7 'Copulatory duct: spermathecal junction' / posterior lateral_or_anterior, 8 Copulatory_duct_loops_relative_to_spermathecae / apart 'encircling (Fig. 93J)', 9 Copulatory_duct_terminal_sclerotization / as_rest_of_duct_ 'distinctly sclerotized, clearly more than rest of duct ', 10 Hard_sclerotized_CD_region / mostly_or_entirely_ectal_to_the_ectal_rim_of_the_spermathecae 'caudal to the spermathecae, mesal to ectal margin of spermathecae', 11 Male_palpal_tibial_rim / uniform_or_only_slightly_asymmetric 'strongly and asymmetrically protruding, scoop-shaped (Fig 36D)', 12 Male_palpal_tibia_prolateral_trichobothria / one none, 13 Cymbial_ridge_ectal_setae / unmodified 'strongly curved towards the palpal bulb (Kochiura, Figs. 51B-C, 52C)', 14 Cymbial_distal_promargin / entire 'with an apophysis (Argyrodes, Figs.) ', 15 Cymbial_mesal_margin / entire 'incised (Anelosimus, Figs. 17D, 20A) ' deeply_notched, 16 Cymbial_tip_sclerotization / like_rest_of_cymbium 'lightly sclerotized, appears white', 17 Cymbial_tip_setae / like_other_setae 'thick and strongly curved (Kochiura, Figs. 51B, 52C)', 18 Cymbial_sheath / absent present, 19 Lock_placement / 'distal (Figs. 67B, 92F-G, I, M)' 'central (Fig. 92H)', 20 Lock_mechanism / 'hook (Figs 31F, 60D, 91A, 92D-E, J-L)' 'hood (Figs 18A, 75B, 92F-I, M)' 'Theridula (Fig 81D)', 21 Cymbial_hook_orientation / 'facing downwards (Figs. 91A, 92D-E, J-K)' 'facing upwards (Fig. 60C-D, 92L)', 22 Cymbial_hook_location / 'inside cymbium (Fig. 92D-E, J-K)' 'ectal cymbial margin (Figs. 67B, 92L).', 23 Cymbial_hook_distal_portion / 'blunt (Figs. 31F, 92D-E)' 'tapering to a narrow tongue (Figs. 66B, 67D, 92L)', 24 Cymbial_hood_size / 'narrow (Fig. 92F-H)' 'broad (Fig. 92I)' 'Spintharus (Fig. 92M)', 25 Cymbial_hood_region / 'translucent, hood visible through cymbium (Anelosimus, Figs. 90A, 91C)' 'opaque, hood not visible', 26 Alveolus_shape / 'circular or oval (Fig. 92A-H)' 'with a mesal extension (Fig. 92A)', 27 Tegulum_ectal_margin / entire 'protruded (Fig. 20D)', 28 Tegular_groove / absent 'present (Fig. 28B)', 29 SDT_SB_I / separate touching, 30 'SDT post-SB II turn' / gradual '90 degrees (Anelosimus, Fig. 93B)', 31 SDT_SB_I_&_II_reservoir_segment_alignment / divergent parallel, 32 SDT_SB_I_&_II_orientation / in_plane_of_first_loop_from_fundus 'out of plane of first loop, against tegular wall', 33 SDT_RSB_I_&_II / absent present, 34 SDT_SB_III / absent present, 35 SDT_SB_IV / absent 'present (Fig. 93E)', 36 Conductor_shape / 'simple, round or oval, short' 'fan shaped, narrow base and broad tip (Selkirkiella, Kochiura)' Enoplognatha Argyrodes Achaearanea Theridion '''rupununi''' '''tanzania''' '''cup-shaped''', 37 Conductor / 'with a groove for embolus (Figs. 10A, 28D, 69B)' 'entire (Figs. 13D, 17F, 52C-D)', 38 Conductor_surface / 'smooth (Figs. 75B, 77B-C)' ' heavily ridged (Figs. 10B-C, 44D. 67C, 69D)', 39 Conductor_tip_sclerotization / like_base more_than_base, 40 Subconductor / absent present, 41 Subconductor_pit_upper_wall / 'entire, or slightly protruding' forms_a_regular_oval_lip, 42 Subconductor_at_C_base / narrows_abruptly_before_C_base narrows_gradually_along_its_entire_length broad_at_base, 43 'Embolus tail-SC relation' / 'hooked in, or oriented towards SC' surpasses_SC behind_E_base, 44 Tegulum_ectally_ / occupying_less_than_half_of_the_cymbial_cavity_ occupying_more_than_half_of_the_cymbial_cavity, 45 MA_and_sperm_duct / sperm_duct_loop_not_inside_MA 'sperm duct loop inside MA (Figs. 90F, 91B)', 46 'MA-tegular membrane connection' / broad narrow, 47 MA_form / unbranched 'two nearly equally sized branches (Fig. 22A-B) ', 48 MA_distal_tip / entire hooded, 49 MA_hood_form / 'narrow, pit-like (Figs. 31F, 34D)' 'scoop-shaped (Figs. 60D, 66B, 67D)', 50 TTA_form / entire 'grooved (Fig. 44C)', 51 TTA / bulky 'prong shaped (vittatus group)', 52 TTA_distal_tip / entire_or_gently_curved Argyrodes 'hooked (branched)', 53 TTA_hook_distal_branch / barely_exceeding_lower_branch_ 'extending beyond lower branch (jucundus group) ', 54 TTA_hook_distal_branch / thick_ 'thin, finger like (domingo, dubiosus)', 55 TTA_hook_proximal_branch / 'blunt, broad' 'flattened, bladelike' 'cylindrical, elongated', 56 TTA_surface_subterminally / smooth ridged, 57 TTA_tip_surface / smooth 'ridged (Figs. 7A-B, 17F, 31D, 34D, 54A, 56B, 86A)', 58 Embolus_and_TTA / loosely_associated_to_or_resting_in_TTA_shallow_groove 'parts of E entirely enclosed in TTA (Figs. 37A-B, 44C, 89C)', 59 Embolus_tip_surface / smooth denticulate, 60 Embolus_spiral_curviture / gentle whip_like corkscrew, 61 Embolus_tip / entire bifid, 62 Embolus_origin / retroventral_on_tegulum 'retrolateral (ectal), partially or completely hidden by cymbium (Figs 44C, 60A-C, 67B)', 63 Embolus_ridges / absent present, 64 Embolus_shape / short_to_moderately_elongate 'extremely long, >2 spirals (Figs. 54D, 73A-E)', 65 Embolus_spiral_width / 'thin, much of E spiral subequal to E tip ' 'thick, entire E spiral much broader than tip ', 66 Embolus_distal_rim / 'entire (normal)' deeply_grooved, 67 Embolic_terminus / abrupt 'with a distal apophysis (EA, Fig. 34E) ', 68 Embolus_tail / 'entire, smooth' 'distinct, lobed', 69 'Embolus-dh connection grooves' / absent present, 70 'Embolus-dh grooves' / 'deep, extend into the E base more than twice longer than the distance between them' 'short, extend into the E base about as long, or slightly longer than the distance between them', 71 E_spiral_distally / 'relatively thin or filiform, cylindrical' 'thick, not cylindrical' 'rupununi/lorenzo like', 72 Embolus_spiral / entire 'biparted (Eb)' pars_pendula, 73 Eb_orientation / towards_embolus_tip towards_tibia, 74 Embolic_division_b / separates_early_from_E E_and_Eb_tightly_associated_the_entire_spiral, 75 Embolic_division_b / broad 'narrow, relative to Eb spiral, snout-like', 76 'Eb distal portion, ectal marginl' / 'level, not raised ' with_a_distinct_ridge_, 77 Eb_form / flat 'globose, inflated', 78 Eb_form / 'distinct, clearly separate apophysis' 'short, confined to first section of spiral, barely separate', 79 Eb_tip_and_E_tip_association / separate Eb_and_E_tips_juxtaposed 'E tip rests on Eb ''cup''', 80 Eb_snout / 'short, snug with E spiral ' 'long, separate from E spiral ', 81 Distal_portion_of_Eb / entire with_a_cup_shaped_apophysis with_a_raised_ridge, 82 E_tail / lobe_not_reaching_ectal_margin_of_Eb_ lobe_touching_ectal_margin_of_Eb_, 83 Extra_tegular_sclerite / absent_ present_, 84 'Median eyes (male)' / flush_with_carapace 'on tubercle (Argyrodes)', 85 'AME size (male)' / subequal_or_slightly_larger_than_ALE clearly_smaller_than_ALE, 86 Cheliceral_posterior_margin / toothed smooth, 87 Cheliceral_posterior_tooth_number / three_or_more two one, 88 Cheliceral_furrow / smooth denticulate, 89 Carapace_hairiness / 'sparsely or patchily hirsute (Fig. 48D)' 'uniformly hirsute (Fig. 71D)', 90 Carapace_pars_stridens / irregular regular_parallel_ridges, 91 Interocular_area / more_or_less_flush_with_clypeus projecting_beyond_clypeus, 92 Clypeus / concave_or_flat with_a_prominent_projection, 93 'ocular and clypeal region setae distribution (male)' / sparse 'in a dense field, or fields', 94 'Labium-sternum connection' / 'visible seam (Fig. 27C)' fused, 95 Sternocoxal_tubercles / present absent, 96 Pedicel_location / 'anterior (Fig. 94A-D)' 'medial (Fig. 94J-K)', 97 Abdominal_folium_pattern / bilateral_spots_or_blotches distinct_central_band_, 98 Abdomen_pattern / Anelosimus_, 99 Dorsal_band / 'dark edged by white (Kochiura, Anelosimus, Fig. 94G, J)' 'light edged by dark (Fig. 94H)' 'Ameridion, light edged by white (Fig. 94I)', 100 Abdominal_dot_pigment / silver 'non-reflective, dull', 101 SPR_form / 'weakly keeled (Figs. 67F, 74F)' 'strongly keeled and elongate (Figs. 16B-C, 24D-E, 42F)', 102 SPR_pick_number / '1-4' '6-28' '>30', 103 SPR_insertion / flush_with_abdominal_surface 'on a ridge (Figs 32D, 72A-B)', 104 'SPR mesally-oriented picks' / absent present, 105 'SPR mesally-oriented picks relative to sagittal plane' / angled_dorsally perpendicular_or_angled_ventrally, 106 SPR / straight_or_slightly_irregular distinctly_curved 'argyrodine, dorsal picks aside others', 107 SPR_dorsal_pick_spacing / subequal_to_ventral_pick_spacing distinctly_compressed, 108 SPR_relative_to_pedicel / lateral dorsal, 109 SPR_setae / separate tight, 110 'Supra pedicillate ventrolateral (4 o''clock) proprioreceptor' / absent present, 111 Epiandrous_fusule_arrangement / in_one_pair_of_sockets in_a_row, 112 Epiandrous_fusule_pair_number / '=>9' '6-8' '4-5' 1, 113 Colulus / 'present (Figs. 45E, 61F)' 'absent (Figs. 16E, 78A)' 'invaginated (Figs. 9D, 63G)', 114 Colulus_size / 'large and fleshy (Figs. 55H, 61F)' 'small, less than half the length of its setae (Fig. 38B)', 115 Colular_setae / present absent, 116 'Colular setae number (female)' / three_or_more two_, 117 'Palpal claw dentition (female)' / 'dense, > half of surface covered by denticles (Figs. 2D, 9E, 11D, 12G, 45G, 47E, 58G, 80D)' 'sparse < half of surface with denticles', 118 'Palpal tibial trichobothria (female)' / four three two five, 119 Femur_I_relative_to_II / subequal 'robust, clearly larger than femur II', 120 'Leg IV relative length (male)' / '3rd longest (typical leg formula 1243)' '2nd longest (typical leg formula 1423)' 'longest (typical leg formula 4123)', 121 'Leg IV relative length (female)' / 3rd_longest 2nd_longest longest_, 122 'Femur vs. metatarsus length (female)' / metatarsus_longer metatarsus_shorter, 123 'Femur vs. metatarsus length (male)' / metatarsus_longer metatarsus_shorter, 124 'Metatarsus vs. tibia length (female)' / metatarsus_longer metatarsus_shorter, 125 'Metatarsus vs. tibia length (male)' / metatarsus_longer metatarsus_shorter, 126 Metatarsal_ventral_macrosetae / like_other_macrosetae thickened_ventrally, 127 Tarsus_IV_comb_serrations / 'simple, straight' curved_hooks, 128 Tarsal_organ_size / 'smaller than setal sockets (normal)' enlarged, 129 'Tarsus IV central claw vs. laterals (male)' / 'short, at most subequal' 'elongate, longer (Figs. 19E, 21C, 23D, 32H, 57F, 58F)', 130 'Tarsus IV central claw vs. laterals (female)' / equal_or_shorter stout_and_distinctly_longer minute, 131 Spinneret_insertion / abdominal_apex 'subapical, abdomen extending beyond spinnerets', 132 PLS_flagelliform_spigot_length / subequal_to__PLS_CY 'longer than PLS CY (Figs. 68E, 78B, 82D)', 133 'PLS, PMS CY spigot bases' / 'not modified, subequal or smaller than ampullates' 'huge and elongated, much larger than ampullates ', 134 CY_shaft_surface / smooth grooved, 135 PLS_AC_spigot_number / five_or_more four_or_less, 136 PLS_flagelliform_spigot / present absent, 137 PLS_posterior_AG_spigot_shape / 'normal, round' flattened, 138 PLS_theridiid_type_AG_position / more_or_less_parallel end_to_end, 139 'PMS minor ampullate (mAP) spigot shaft length' / 'short, subequal to CY shaft' clearly_longer_than_any_CY_shaft, 140 Web_form / 'linyphioid-like sheet web (Fig. 99C)' 'cobweb (Figs. 97G, 99A-B, 100A-F, 101A-E)' 'network mesh web - with foraging field below (rupununi/lorenzo)' 'dry line-web', 141 'Knock-down lines' / absent present, 142 Sticky_silk_in_web / present absent, 143 Egg_sac_surface / spherical_to_lenticular 'stalked (Fig. 88E, 98D).', 144 Egg_case_structure / suboval_or_roundish basal_knob rhomboid elongated Spiky, 145 Web_construction / solitary communal, 146 Mating_thread / present absent, 147 Adult_females_per_nest / one multiple, 148 cooperative_behavior / solitary subsocial permanent_sociality ;
|
746
|
+
MATRIX
|
747
|
+
fooo 01 more stuff here that should not be hit"
|
748
|
+
|
749
|
+
builder = NexusFile::Builder.new
|
750
|
+
lexer = NexusFile::Lexer.new(input)
|
751
|
+
|
752
|
+
(0..147).each{builder.stub_chr()}
|
753
|
+
|
754
|
+
NexusFile::Parser.new(lexer,builder).parse_chr_state_labels
|
755
|
+
|
756
|
+
foo = builder.nexus_file
|
757
|
+
assert_equal 10, foo.characters.size
|
758
|
+
assert_equal "Tibia_II", foo.characters[0].name
|
759
|
+
assert_equal "norm", foo.characters[0].states["0"].name
|
760
|
+
assert_equal "modified", foo.characters[0].states["1"].name
|
761
|
+
|
762
|
+
assert_equal "TII_macrosetae", foo.characters[1].name
|
763
|
+
assert_equal "= TI", foo.characters[1].states["0"].name
|
764
|
+
assert_equal "stronger", foo.characters[1].states["1"].name
|
765
|
+
|
766
|
+
assert_equal "Femoral_tuber", foo.characters[2].name
|
767
|
+
assert_equal "abs", foo.characters[2].states["0"].name
|
768
|
+
assert_equal "pres", foo.characters[2].states["1"].name
|
769
|
+
assert_equal "m-setae", foo.characters[2].states["2"].name
|
770
|
+
|
771
|
+
assert_equal "Undefined", foo.characters[3].name
|
772
|
+
assert_equal 0, foo.characters[3].states.keys.size
|
773
|
+
|
774
|
+
assert_equal "Cymbium", foo.characters[4].name
|
775
|
+
assert_equal "dorsal", foo.characters[4].states["0"].name
|
776
|
+
assert_equal "mesal", foo.characters[4].states["1"].name
|
777
|
+
assert_equal "lateral", foo.characters[4].states["2"].name
|
778
|
+
|
779
|
+
assert_equal "Paracymbium", foo.characters[5].name
|
780
|
+
assert_equal "abs", foo.characters[5].states["0"].name
|
781
|
+
assert_equal "pres", foo.characters[5].states["1"].name
|
782
|
+
|
783
|
+
assert_equal "Globular_tegulum", foo.characters[6].name
|
784
|
+
assert_equal "abs", foo.characters[6].states["0"].name
|
785
|
+
assert_equal "pres", foo.characters[6].states["1"].name
|
786
|
+
|
787
|
+
assert_equal "Undefined", foo.characters[7].name
|
788
|
+
assert_equal "entire", foo.characters[7].states["0"].name
|
789
|
+
assert_equal "w_lobe", foo.characters[7].states["1"].name
|
790
|
+
|
791
|
+
# ...
|
792
|
+
|
793
|
+
assert_equal "Median_apophysis", foo.characters[9].name
|
794
|
+
assert_equal "pres", foo.characters[9].states["0"].name
|
795
|
+
assert_equal "abs", foo.characters[9].states["1"].name
|
796
|
+
end
|
797
|
+
|
798
|
+
|
799
|
+
|
800
|
+
def test_parse_notes_blk
|
801
|
+
input ="
|
802
|
+
TEXT TAXA = 'Scharff&Coddington_1997_Araneidae' TAXON = 2 TEXT = 'This is a footnote to taxon 2, Uloborus';
|
803
|
+
|
804
|
+
TEXT TAXON = 4 CHARACTER = 8 TEXT = This_is_a_footnote_to_a_cell.;
|
805
|
+
|
806
|
+
TEXT CHARACTER = 10 TEXT = This_is_footnote_to_char_10;
|
807
|
+
|
808
|
+
TEXT FILE TEXT = 'Scharff, N. and J. A. Coddington. 1997. A phylogenetic analysis of the orb-weaving spider family Araneidae (Arachnida, Araneae). Zool. J. Linn. Soc. 120(4): 355?434';
|
809
|
+
|
810
|
+
AN T = 4 A = JC DC = 2008.4.13.20.31.19 DM = 2008.4.13.20.31.38 ID = 01194a57d0161 I = _ TF = (CM 'This is an \"annotation\" to taxon 4') ;
|
811
|
+
|
812
|
+
AN C = 4 A = JC DC = 2008.4.13.20.31.50 DM = 2008.4.13.20.32.10 ID = 01194a584b9f2 I = _ TF = (CM 'This is an annotation to charcter 4, that has no name.') ;
|
813
|
+
|
814
|
+
AN T = 9 C = 3 A = 0 DC = 2008.4.20.17.24.36 DM = 2008.4.20.17.25.4 ID = 01196db963874 I = _ TF = (CM 'This is an annotation to chr 3, taxa 9, coded ?') ;
|
815
|
+
|
816
|
+
AN T = 2 C = 6 A = JC DC = 2008.4.13.20.35.20 DM = 2008.4.13.20.35.36 ID = JC1194a5b7e1a3 I = _ TF = (CM 'This is an annotation that haa a hard return in it^n^n^n^nSo there!') ;
|
817
|
+
|
818
|
+
AN T = 7 C = 10 A = 0 DC = 2008.4.20.17.25.11 DM = 2008.4.20.17.26.1 ID = 01196db9ebd25 I = _ TF = (CM 'this is an annotation^nwith several hard returns^nfor a cell of taxa 6, chr 9 (from zero)^ncoded as -') ;
|
819
|
+
|
820
|
+
AN T = 2 C = 6 A = JC DC = 2008.4.13.20.35.20 DM = 2008.4.13.20.35.36 ID = JC1194a5b7e1a3 I = _ TF = (CM 'This is ANOTHER annotation that haa a hard return in it^n^n^n^nSo there!') ;
|
821
|
+
|
822
|
+
END; Don't parse this bit, eh?"
|
823
|
+
|
824
|
+
# note the second last note note embedds parens in the value
|
825
|
+
|
826
|
+
builder = NexusFile::Builder.new
|
827
|
+
lexer = NexusFile::Lexer.new(input)
|
828
|
+
|
829
|
+
# stubs
|
830
|
+
(0..9).each{builder.stub_chr()}
|
831
|
+
(0..9).each{builder.stub_taxon()}
|
832
|
+
builder.nexus_file.codings[3] = []
|
833
|
+
builder.nexus_file.codings[3][7] = NexusFile::NexusFile::Coding.new()
|
834
|
+
builder.nexus_file.codings[8] = []
|
835
|
+
builder.nexus_file.codings[8][2] = NexusFile::NexusFile::Coding.new()
|
836
|
+
builder.nexus_file.codings[1] = []
|
837
|
+
builder.nexus_file.codings[1][5] = NexusFile::NexusFile::Coding.new()
|
838
|
+
builder.nexus_file.codings[6] = []
|
839
|
+
builder.nexus_file.codings[6][9] = NexusFile::NexusFile::Coding.new()
|
840
|
+
builder.nexus_file.codings[3] = []
|
841
|
+
builder.nexus_file.codings[3][7] = NexusFile::NexusFile::Coding.new()
|
842
|
+
|
843
|
+
NexusFile::Parser.new(lexer,builder).parse_notes_blk
|
844
|
+
|
845
|
+
foo = builder.nexus_file
|
846
|
+
|
847
|
+
# make sure stubs are setup
|
848
|
+
assert_equal 10, foo.characters.size
|
849
|
+
assert_equal 10, foo.taxa.size
|
850
|
+
|
851
|
+
assert_equal 1, foo.taxa[1].notes.size
|
852
|
+
assert_equal 1, foo.codings[3][7].notes.size
|
853
|
+
assert_equal 'This_is_a_footnote_to_a_cell.', foo.codings[3][7].notes[0].note
|
854
|
+
|
855
|
+
assert_equal 1, foo.characters[9].notes.size
|
856
|
+
assert_equal 'This_is_footnote_to_char_10', foo.characters[9].notes[0].note
|
857
|
+
|
858
|
+
assert_equal 1, foo.notes.size
|
859
|
+
assert_equal 'Scharff, N. and J. A. Coddington. 1997. A phylogenetic analysis of the orb-weaving spider family Araneidae (Arachnida, Araneae). Zool. J. Linn. Soc. 120(4): 355?434', foo.notes[0].note
|
860
|
+
|
861
|
+
assert_equal 1, foo.taxa[3].notes.size
|
862
|
+
assert_equal 1, foo.characters[3].notes.size
|
863
|
+
assert_equal 1, foo.codings[8][2].notes.size
|
864
|
+
assert_equal 1, foo.codings[6][9].notes.size
|
865
|
+
assert_equal 2, foo.codings[1][5].notes.size # TWO!!
|
866
|
+
assert_equal 1, foo.codings[3][7].notes.size
|
867
|
+
|
868
|
+
|
869
|
+
assert_equal "This_is_a_footnote_to_a_cell.", foo.codings[3][7].notes[0].note
|
870
|
+
|
871
|
+
assert_equal "This is an annotation to chr 3, taxa 9, coded ?", foo.codings[8][2].notes[0].note
|
872
|
+
assert_equal "This is an annotation that haa a hard return in it^n^n^n^nSo there!", foo.codings[1][5].notes[0].note
|
873
|
+
assert_equal "this is an annotation^nwith several hard returns^nfor a cell of taxa 6, chr 9 (from zero)^ncoded as -", foo.codings[6][9].notes[0].note
|
874
|
+
assert_equal "This is ANOTHER annotation that haa a hard return in it^n^n^n^nSo there!", foo.codings[1][5].notes[1].note
|
875
|
+
|
876
|
+
end
|
877
|
+
|
878
|
+
def test_notes_block_2
|
879
|
+
input="
|
880
|
+
TEXT CHARACTER = 1 TEXT = A62.001;
|
881
|
+
TEXT CHARACTER = 2 TEXT = A62.002;
|
882
|
+
TEXT CHARACTER = 3 TEXT = A62.003;
|
883
|
+
TEXT CHARACTER = 4 TEXT = A62.004;
|
884
|
+
TEXT CHARACTER = 5 TEXT = A62.005;
|
885
|
+
TEXT CHARACTER = 6 TEXT = A62.006;
|
886
|
+
TEXT CHARACTER = 7 TEXT = A62.007;
|
887
|
+
TEXT CHARACTER = 8 TEXT = A62.008;
|
888
|
+
end;
|
889
|
+
"
|
890
|
+
|
891
|
+
# note the second last note note embeds parens in the value
|
892
|
+
|
893
|
+
builder = NexusFile::Builder.new
|
894
|
+
lexer = NexusFile::Lexer.new(input)
|
895
|
+
# stubs
|
896
|
+
(0..9).each{builder.stub_chr()}
|
897
|
+
|
898
|
+
NexusFile::Parser.new(lexer,builder).parse_notes_blk
|
899
|
+
|
900
|
+
foo = builder.nexus_file
|
901
|
+
|
902
|
+
# make sure stubs are setup
|
903
|
+
assert_equal 10, foo.characters.size
|
904
|
+
|
905
|
+
assert_equal 'A62.001', foo.characters[0].notes[0].note
|
906
|
+
assert_equal 'A62.002', foo.characters[1].notes[0].note
|
907
|
+
assert_equal 'A62.003', foo.characters[2].notes[0].note
|
908
|
+
assert_equal 'A62.004', foo.characters[3].notes[0].note
|
909
|
+
assert_equal 'A62.005', foo.characters[4].notes[0].note
|
910
|
+
assert_equal 'A62.006', foo.characters[5].notes[0].note
|
911
|
+
assert_equal 'A62.007', foo.characters[6].notes[0].note
|
912
|
+
assert_equal 'A62.008', foo.characters[7].notes[0].note
|
913
|
+
assert_equal NexusFile::NexusFile::Character, foo.characters[7].class
|
914
|
+
assert_equal 1, foo.characters[7].notes.size
|
915
|
+
end
|
916
|
+
|
917
|
+
|
918
|
+
def test_parse_trees_block
|
919
|
+
end
|
920
|
+
|
921
|
+
def test_parse_labels_block
|
922
|
+
end
|
923
|
+
|
924
|
+
def test_parse_sets_block
|
925
|
+
end
|
926
|
+
|
927
|
+
def test_parse_assumptions_block
|
928
|
+
end
|
929
|
+
|
930
|
+
def DONT_test_misc
|
931
|
+
nf = File.read('foo.nex') # MX_test_01.nex
|
932
|
+
foo = parse_nexus_file(nf)
|
933
|
+
assert true, foo
|
934
|
+
end
|
935
|
+
|
936
|
+
end
|
937
|
+
|