bio-nexml 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,633 @@
1
+ require 'bio/db/nexml/writer'
2
+
3
+ module Bio
4
+ module NeXML
5
+
6
+ module TestWriterHelper
7
+ # This module defines test helpers.
8
+ # TEST_FILE_PATH points to a very small nexml file that defines all the nexml elements.
9
+ # The idea is to initialize two XML::Node objects: first, by parsing the test file, and
10
+ # the second by calling serialize_* methods on NeXML::Writer object and assert their equality.
11
+ # If they are equal, the NeXML::Writer#serialize_* methods pass the test. This equality is
12
+ # asserted by the match? helper method defined in this module.
13
+
14
+ TEST_FILE_PATH = File.join File.dirname(__FILE__), ['..'] * 4, 'data', 'nexml', 'test.xml'
15
+
16
+ # Parse the test file.
17
+ def parse
18
+ @doc = XML::Document.file TEST_FILE_PATH, :options => XML::Parser::Options::NOBLANKS
19
+ end
20
+
21
+ # Return the first occurence of a tag by name in the test file.
22
+ def element( name )
23
+ @doc.find( "//nex:#{name}", 'nex:http://www.nexml.org/2009' )
24
+ end
25
+
26
+ # If an attribte is associated with a namespace, say: 'xsi:type', the XML::Attr#name function
27
+ # returns the name without the namespace prefix. The redefined XML::Attr#name returns the
28
+ # qualified name( with the prefix ) of the node.
29
+ XML::Attr.class_eval do
30
+ alias old_name name
31
+ def name
32
+ return old_name unless self.ns?
33
+ "#{self.ns.prefix}:#{old_name}"
34
+ end
35
+ end
36
+
37
+ # Compare two XML::Nodes for equality based on the following criteria:
38
+ # * same name,
39
+ # * same attributes( irrespective of the order )
40
+ # * same children( irrespective of the order )
41
+ def match?( node1, node2 )
42
+ # not equal if their names do not match
43
+
44
+ attributes1 = node1.attributes.map( &:to_s )
45
+ attributes2 = node2.attributes.map( &:to_s )
46
+
47
+ # not equal if both do not have the same number of attributes
48
+ return false unless attributes1.length == attributes2.length
49
+
50
+ # if the nodes have same number of attributes, compare them
51
+ unless attributes1.empty? and attributes2.empty?
52
+ attributes1.each do |attr1|
53
+ # not equal if attr1 can not be found in attributes2
54
+ return false unless attributes2.find{ |attr2| attr1 == attr2 }
55
+ end
56
+ end
57
+
58
+ children1 = node1.children
59
+ children2 = node2.children
60
+
61
+ # not equal if number of child nodes do not match
62
+ return false unless children1.length == children2.length
63
+
64
+ # if the nodes have same number of children, compare them
65
+ unless children1.empty? and children2.empty?
66
+ children1.each do |child1|
67
+ #not equal if child1 can't be found in children2
68
+ return false unless children2.find{ |child2| match?( child1, child2 ) }
69
+ end
70
+ end
71
+
72
+ true
73
+ end
74
+
75
+ end
76
+
77
+ class TestTestWriterHelper < Test::Unit::TestCase
78
+ include TestWriterHelper
79
+
80
+ # should pass the criteria( see the definition of match? ) of a node's equality.
81
+ def test_match
82
+ # two nodes with same name
83
+ node1 = XML::Node.new( 'nexml' )
84
+ node2 = XML::Node.new( 'nexml' )
85
+
86
+ # same attributes
87
+ node1.attributes = { :version => '0.9', :generator => 'bioruby' }
88
+ node2.attributes = { :generator => 'bioruby', :version => '0.9' }
89
+
90
+ # childe nodes for node1
91
+ child11 = XML::Node.new( 'otus' )
92
+ child12 = XML::Node.new( 'otus' )
93
+ child11.attributes = { :id => 'taxa1', :label => 'Taxa 1' }
94
+ child12.attributes = { :id => 'taxa2', :label => 'Taxa 2' }
95
+
96
+ # childe nodes for node2
97
+ child21 = XML::Node.new( 'otus' )
98
+ child22 = XML::Node.new( 'otus' )
99
+ child21.attributes = { :id => 'taxa1', :label => 'Taxa 1' }
100
+ child22.attributes = { :id => 'taxa2', :label => 'Taxa 2' }
101
+
102
+ # same children
103
+ node1 << child11
104
+ node1 << child12
105
+ node2 << child22
106
+ node2 << child21
107
+
108
+ assert match?( node1, node2 )
109
+ end
110
+ end
111
+
112
+ class TestWriter < Test::Unit::TestCase
113
+ include TestWriterHelper
114
+
115
+ def setup
116
+ @writer = Bio::NeXML::Writer.new; parse
117
+ end
118
+
119
+ # should respond properly to :id, and :label
120
+ def test_attributes_1
121
+ otu1 = Bio::NeXML::Otu.new( 'o1', :label => 'otu 1' )
122
+ otu2 = Bio::NeXML::Otu.new( 'o2' )
123
+
124
+ ae1 = { :id => 'o1', :label => 'otu 1' }
125
+ ae2 = { :id => 'o2' }
126
+
127
+ aa1 = @writer.send( :attributes, otu1, :id, :label )
128
+ aa2 = @writer.send( :attributes, otu2, :id, :label )
129
+
130
+ assert_equal ae1, aa1
131
+ assert_equal ae2, aa2
132
+ end
133
+
134
+ # should respond properly to :symbol
135
+ def test_attributes_2
136
+ ds = Bio::NeXML::State.new( 'ds1', 'A' )
137
+ ss = Bio::NeXML::State.new( 'ss1', '1' )
138
+
139
+ ae1 = { :symbol => 'A' }
140
+ ae2 = { :symbol => '1' }
141
+
142
+ aa1 = @writer.send( :attributes, ds, :symbol )
143
+ aa2 = @writer.send( :attributes, ss, :symbol )
144
+
145
+ assert_equal ae1, aa1
146
+ assert_equal ae2, aa2
147
+ end
148
+
149
+ # should respond properly to :"xsi:type"
150
+ def test_attributes_3
151
+ t = Bio::NeXML::IntTree.new 'tree1'
152
+ n = Bio::NeXML::FloatNetwork.new 'network1'
153
+ dc1 = Bio::NeXML::DnaSeqs.new( 'dnacharacters1' )
154
+ dc2 = Bio::NeXML::DnaCells.new( 'dnacharacters2' )
155
+
156
+ ae1 = { :"xsi:type" => "nex:IntTree" }
157
+ ae2 = { :"xsi:type" => "nex:FloatNetwork" }
158
+ ae3 = { :"xsi:type" => "nex:DnaSeqs" }
159
+ ae4 = { :"xsi:type" => "nex:DnaCells" }
160
+
161
+ aa1 = @writer.send( :attributes, t, :"xsi:type" )
162
+ aa2 = @writer.send( :attributes, n, :"xsi:type" )
163
+ aa3 = @writer.send( :attributes, dc1, :"xsi:type" )
164
+ aa4 = @writer.send( :attributes, dc2, :"xsi:type" )
165
+
166
+ assert_equal ae1, aa1
167
+ assert_equal ae2, aa2
168
+ assert_equal ae3, aa3
169
+ assert_equal ae4, aa4
170
+ end
171
+
172
+ # should respond properly to :root and :otu
173
+ def test_attributes_4
174
+ o = Bio::NeXML::Otu.new( 'o1' )
175
+ n1 = Bio::NeXML::Node.new( 'n1', :otu => o, :root => true )
176
+ n2 = Bio::NeXML::Node.new( 'n2' )
177
+
178
+ ae1 = { :otu => 'o1', :root => 'true' }
179
+ ae2 = {}
180
+
181
+ aa1 = @writer.send( :attributes, n1, :otu, :root )
182
+ aa2 = @writer.send( :attributes, n2, :otu, :root )
183
+
184
+ assert_equal ae1, aa1
185
+ assert_equal ae2, aa2
186
+ end
187
+
188
+ # should respond properly to :otus
189
+ def test_attributes_5
190
+ o = Bio::NeXML::Otus.new( 'o1' )
191
+ t = Bio::NeXML::Trees.new( 't1', :otus => o )
192
+
193
+ ae = { :otus => 'o1' }
194
+ aa = @writer.send( :attributes, t, :otus )
195
+
196
+ assert_equal ae, aa
197
+ end
198
+
199
+ # shold respond properly to :char and :state
200
+ def test_attributes_6
201
+ cc = Bio::NeXML::ContinuousCell.new
202
+ cc.char = Bio::NeXML::Char.new( 'cc1' )
203
+ cc.state = '-0.9'
204
+ dc = Bio::NeXML::Cell.new
205
+ dc.char = Bio::NeXML::Char.new( 'dc1', nil )
206
+ dc.state = Bio::NeXML::State.new 'ds1', 'A'
207
+
208
+ ae1 = { :char => 'cc1', :state => '-0.9' }
209
+ ae2 = { :char => 'dc1', :state => 'ds1' }
210
+
211
+ aa1 = @writer.send( :attributes, cc, :char, :state )
212
+ aa2 = @writer.send( :attributes, dc, :char, :state )
213
+
214
+ assert_equal ae1, aa1
215
+ assert_equal ae2, aa2
216
+ end
217
+
218
+ # shold respond properly to :source and :target and :length
219
+ def test_attributes_7
220
+ n1 = Bio::NeXML::Node.new 'n1'
221
+ n2 = Bio::NeXML::Node.new 'n2'
222
+ e = Bio::NeXML::IntEdge.new 'e1', :source => n1, :target => n2
223
+ re = Bio::NeXML::RootEdge.new 're1', :target => n1, :length => 2
224
+
225
+ ae1 = { :source => 'n1', :target => 'n2', :length => '0' }
226
+ ae2 = { :target => 'n1', :length => '2' }
227
+
228
+ aa1 = @writer.send( :attributes, e, :source, :target, :length )
229
+ aa2 = @writer.send( :attributes, re, :source, :target, :length )
230
+
231
+ assert_equal ae1, aa1
232
+ assert_equal ae2, aa2
233
+ end
234
+
235
+ # shold respond properly to :states
236
+ def test_attributes_8
237
+ ds = Bio::NeXML::States.new( 'ds1' )
238
+ dc = Bio::NeXML::Char.new( 'dc1', :states => ds )
239
+
240
+ ae = { :states => 'ds1' }
241
+
242
+ aa = @writer.send( :attributes, dc, :states )
243
+
244
+ assert_equal ae, aa
245
+ end
246
+
247
+ # tag should create a XML::Node
248
+ def test_create_node
249
+ node1 = XML::Node.new( 'nexml' )
250
+ node1.attributes = { :version => '0.9' }
251
+
252
+ node2 = @writer.send( :create_node, 'nexml', :version => '0.9' )
253
+
254
+ assert_equal node1, node2
255
+ end
256
+
257
+ def test_serialize_otu
258
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
259
+ output = o1.to_xml
260
+ parsed = element( 'otu' ).first
261
+ assert match?( parsed, output )
262
+ end
263
+
264
+ def test_serialize_otus
265
+ taxa1 = Bio::NeXML::Otus.new 'taxa1', :label => 'A taxa block'
266
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
267
+ o2 = Bio::NeXML::Otu.new 'o2', :label => 'A taxon'
268
+ taxa1.add_otu( o1 )
269
+ taxa1.add_otu( o2 )
270
+
271
+ output = taxa1.to_xml
272
+ parsed = element( 'otus' ).first
273
+
274
+ assert match?( parsed, output )
275
+ end
276
+
277
+ def test_serialize_node
278
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
279
+ n1 = Bio::NeXML::Node.new 'n1', :otu => o1, :root => true, :label => 'A node'
280
+
281
+ output = n1.to_xml
282
+ parsed = element( 'node' ).first
283
+
284
+ assert match?( parsed, output )
285
+ end
286
+
287
+ def test_serialize_edge
288
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
289
+ o2 = Bio::NeXML::Otu.new 'o2', :label => 'A taxon'
290
+ n1 = Bio::NeXML::Node.new 'n1', :otu => o1, :root => true, :label => 'A node'
291
+ n2 = Bio::NeXML::Node.new 'n2', :otu => o2, :root => false, :label => 'A node'
292
+ e1 = Bio::NeXML::Edge.new 'e1', :source => n1, :target => n2, :length => 0.4353, :label => 'An edge'
293
+
294
+ output = e1.to_xml
295
+ parsed = element( 'edge' ).first
296
+
297
+ assert match?( parsed, output )
298
+ end
299
+
300
+ def test_serailize_rootedge
301
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
302
+ n1 = Bio::NeXML::Node.new 'n1', :otu => o1, :root => true, :label => 'A node'
303
+ re1 = Bio::NeXML::RootEdge.new 're1', :target => n1, :length => 0.5, :label => 'A rootedge'
304
+
305
+ output = re1.to_xml
306
+ parsed = element( 'rootedge' ).first
307
+
308
+ assert match?( parsed, output )
309
+ end
310
+
311
+ def test_serialize_tree
312
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
313
+ n1 = Bio::NeXML::Node.new 'n1', :otu => o1, :root => true, :label => 'A node'
314
+ n2 = Bio::NeXML::Node.new 'n2', :otu => nil, :root => false, :label => 'A node'
315
+ re1 = Bio::NeXML::RootEdge.new 're1', :target => n1, :length => 0.5, :label => 'A rootedge'
316
+ e1 = Bio::NeXML::Edge.new 'e1', :source => n1, :target => n2, :length => 0.4353, :label => 'An edge'
317
+ tree1 = Bio::NeXML::FloatTree.new 'tree1', :label => 'A float tree'
318
+ tree1.add_node n1
319
+ tree1.add_node n2
320
+ tree1.add_rootedge re1
321
+ tree1.add_edge e1
322
+
323
+ output = tree1.to_xml
324
+ parsed = element( 'tree' ).first
325
+ assert match?( parsed, output )
326
+ end
327
+
328
+ def test_serialize_network
329
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
330
+ n1 = Bio::NeXML::Node.new 'n1n1', :otu => o1, :root => true, :label => 'A node'
331
+ n2 = Bio::NeXML::Node.new 'n1n2', :otu => nil, :root => false, :label => 'A node'
332
+ e1 = Bio::NeXML::Edge.new 'n1e1', :source => n1, :target => n2, :length => 1, :label => 'An edge'
333
+ e2 = Bio::NeXML::Edge.new 'n1e2', :source => n2, :target => n2, :length => 0, :label => 'An edge'
334
+ network1 = Bio::NeXML::IntNetwork.new 'network1', :label => 'An int network'
335
+ network1.add_node n1
336
+ network1.add_node n2
337
+ network1.add_edge e1
338
+ network1.add_edge e2
339
+
340
+ output = network1.to_xml
341
+ parsed = element( 'network' ).first
342
+
343
+ assert match?( parsed, output )
344
+ end
345
+
346
+ def test_serialize_trees
347
+ o1 = Bio::NeXML::Otu.new 'o1', :label => 'A taxon'
348
+
349
+ n1 = Bio::NeXML::Node.new 'n1', :otu => o1, :root => true, :label => 'A node'
350
+ n2 = Bio::NeXML::Node.new 'n2', :otu => nil, :root => false, :label => 'A node'
351
+ re1 = Bio::NeXML::RootEdge.new 're1', :target => n1, :length => 0.5, :label => 'A rootedge'
352
+ e1 = Bio::NeXML::Edge.new 'e1', :source => n1, :target => n2, :length => 0.4353, :label => 'An edge'
353
+ tree1 = Bio::NeXML::FloatTree.new 'tree1', :label => 'A float tree'
354
+
355
+ tree1.add_node n1
356
+ tree1.add_node n2
357
+ tree1.add_rootedge re1
358
+ tree1.add_edge e1
359
+
360
+ n1 = Bio::NeXML::Node.new 'n1n1', :otu => o1, :root => true, :label => 'A node'
361
+ n2 = Bio::NeXML::Node.new 'n1n2', :otu => nil, :root => false, :label => 'A node'
362
+ e1 = Bio::NeXML::Edge.new 'n1e1', :source => n1, :target => n2, :length => 1, :label => 'An edge'
363
+ e2 = Bio::NeXML::Edge.new 'n1e2', :source => n2, :target => n2, :length => 0, :label => 'An edge'
364
+ network1 = Bio::NeXML::IntNetwork.new 'network1', :label => 'An int network'
365
+
366
+ network1.add_node n1
367
+ network1.add_node n2
368
+ network1.add_edge e1
369
+ network1.add_edge e2
370
+
371
+ taxa1 = Bio::NeXML::Otus.new 'taxa1'
372
+ trees1 = Bio::NeXML::Trees.new 'trees1', :otus => taxa1, :label => 'A tree container'
373
+ trees1 << tree1
374
+ trees1 << network1
375
+
376
+ output = trees1.to_xml
377
+ parsed = element( 'trees' ).first
378
+ assert match?( parsed, output )
379
+ end
380
+
381
+ def test_serialize_uncertain_state_set
382
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
383
+ ss2 = Bio::NeXML::State.new 'ss2', :symbol => '2'
384
+ uss1 = Bio::NeXML::State.new 'ss5', :symbol => '5'
385
+ uss1.ambiguity = :uncertain
386
+ uss1.add_member( ss1 )
387
+ uss1.add_member( ss2 )
388
+
389
+ output = uss1.to_xml
390
+ parsed = element( 'uncertain_state_set' ).first
391
+
392
+ assert match?( parsed, output )
393
+ end
394
+
395
+ def test_serialize_polymorphic_state_set
396
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
397
+ ss2 = Bio::NeXML::State.new 'ss2', :symbol => '2'
398
+ pss1 = Bio::NeXML::State.new 'ss4', :symbol => '4'
399
+ pss1.ambiguity = :polymorphic
400
+ pss1.add_member( ss1 )
401
+ pss1.add_member( ss2 )
402
+
403
+ output = pss1.to_xml
404
+ parsed = element( 'polymorphic_state_set' ).first
405
+
406
+ assert match?( parsed, output )
407
+ end
408
+
409
+ def test_serialize_state
410
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
411
+
412
+ output = ss1.to_xml
413
+ parsed = element( 'state' ).first
414
+
415
+ assert match?( parsed, output )
416
+ end
417
+
418
+ def test_serialize_states
419
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
420
+ ss2 = Bio::NeXML::State.new 'ss2', :symbol => '2'
421
+ sss1 = Bio::NeXML::States.new 'sss1'
422
+
423
+ pss1 = Bio::NeXML::State.new 'ss4', :symbol => '4'
424
+ pss1.ambiguity = :polymorphic
425
+ pss1.add_member( ss1 )
426
+ pss1.add_member( ss2 )
427
+
428
+ uss1 = Bio::NeXML::State.new 'ss5', :symbol => '5'
429
+ uss1.ambiguity = :uncertain
430
+ uss1.add_member( ss1 )
431
+ uss1.add_member( ss2 )
432
+
433
+ sss1.add_state( ss1 )
434
+ sss1.add_state( ss2 )
435
+
436
+ sss1.add_state( uss1 )
437
+ sss1.add_state( pss1 )
438
+
439
+ output = sss1.to_xml
440
+ parsed = element( 'states' ).first
441
+
442
+ assert match?( parsed, output )
443
+ end
444
+
445
+ def test_char
446
+ sss1 = Bio::NeXML::States.new 'sss1'
447
+ sc1 = Bio::NeXML::Char.new 'sc1', :states => sss1
448
+
449
+ output = sc1.to_xml
450
+ parsed = element( 'char' ).first
451
+
452
+ assert match?( parsed, output )
453
+ end
454
+
455
+ def test_format
456
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
457
+ ss2 = Bio::NeXML::State.new 'ss2', :symbol => '2'
458
+ sss1 = Bio::NeXML::States.new 'sss1'
459
+
460
+ pss1 = Bio::NeXML::State.new 'ss4', :symbol => '4'
461
+ pss1.ambiguity = :polymorphic
462
+ pss1.add_member( ss1 )
463
+ pss1.add_member( ss2 )
464
+
465
+ uss1 = Bio::NeXML::State.new 'ss5', :symbol => '5'
466
+ uss1.ambiguity = :uncertain
467
+ uss1.add_member( ss1 )
468
+ uss1.add_member( ss2 )
469
+
470
+ sss1.add_state( ss1 )
471
+ sss1.add_state( ss2 )
472
+ sss1.add_state( uss1 )
473
+ sss1.add_state( pss1 )
474
+
475
+ sc1 = Bio::NeXML::Char.new 'sc1', :states => sss1
476
+ sc2 = Bio::NeXML::Char.new 'sc2', :states => sss1
477
+
478
+ sf1 = Bio::NeXML::Format.new
479
+ sf1.add_states( sss1 )
480
+ sf1.add_char( sc1 )
481
+ sf1.add_char( sc2 )
482
+
483
+ output = sf1.to_xml
484
+ parsed = element( 'format' ).first
485
+
486
+ assert match?( parsed, output )
487
+ end
488
+
489
+ def test_serialize_seq
490
+ sseq1 = Bio::NeXML::Sequence.new
491
+ sseq1.value = "1 2"
492
+
493
+ output = sseq1.to_xml
494
+ parsed = element( 'seq' ).first
495
+
496
+ assert match?( parsed, output )
497
+ end
498
+
499
+ def test_serialize_cell
500
+ sss2 = Bio::NeXML::States.new 'sss2'
501
+ ss6 = Bio::NeXML::State.new 'ss6', :symbol => '1'
502
+ sc3 = Bio::NeXML::Char.new 'sc3', :states => sss2
503
+
504
+ scell1 = Bio::NeXML::Cell.new
505
+ scell1.char = sc3
506
+ scell1.state = ss6
507
+
508
+ output = scell1.to_xml
509
+ parsed = element( 'cell' ).first
510
+
511
+ assert match?( parsed, output )
512
+ end
513
+
514
+ def test_sereialize_seq_row
515
+ o1 = Bio::NeXML::Otu.new 'o1'
516
+ sseq1 = Bio::NeXML::Sequence.new
517
+ sseq1.value = "1 2"
518
+ sr1 = Bio::NeXML::SeqRow.new 'sr1', :otu => o1
519
+ sr1.add_sequence( sseq1 )
520
+
521
+ output = sr1.to_xml
522
+ parsed = element( 'row' ).first
523
+
524
+ assert match?( parsed, output )
525
+ end
526
+
527
+ def test_serialize_cell_row
528
+ o1 = Bio::NeXML::Otu.new 'o1'
529
+ sss2 = Bio::NeXML::States.new 'sss2'
530
+ ss6 = Bio::NeXML::State.new 'ss6', :symbol => '1'
531
+ sc3 = Bio::NeXML::Char.new 'sc3', :states => sss2
532
+
533
+ scell1 = Bio::NeXML::Cell.new
534
+ scell1.char = sc3
535
+ scell1.state = ss6
536
+
537
+ sr3 = Bio::NeXML::CellRow.new 'sr3', :otu => o1
538
+ sr3.add_cell( scell1 )
539
+
540
+ output = sr3.to_xml
541
+ parsed = element( 'row' ).last
542
+
543
+ assert match?( parsed, output )
544
+ end
545
+
546
+ def test_serialize_matrix
547
+ o1 = Bio::NeXML::Otu.new 'o1'
548
+ o2 = Bio::NeXML::Otu.new 'o2'
549
+
550
+ sseq1 = Bio::NeXML::Sequence.new
551
+ sseq1.value = "1 2"
552
+
553
+ sseq2 = Bio::NeXML::Sequence.new
554
+ sseq2.value = "2 2"
555
+
556
+ sr1 = Bio::NeXML::SeqRow.new 'sr1', :otu => o1
557
+ sr2 = Bio::NeXML::SeqRow.new 'sr2', :otu => o2
558
+
559
+ sr1.add_sequence( sseq1 )
560
+ sr2.add_sequence( sseq2 )
561
+
562
+ m = Bio::NeXML::Matrix.new
563
+ m.add_row( sr1 )
564
+ m.add_row( sr2 )
565
+
566
+ output = m.to_xml
567
+ parsed = element( 'matrix' ).first
568
+
569
+ assert match?( parsed, output )
570
+ end
571
+
572
+ def test_serialize_characters
573
+ ss1 = Bio::NeXML::State.new 'ss1', :symbol => '1'
574
+ ss2 = Bio::NeXML::State.new 'ss2', :symbol => '2'
575
+ sss1 = Bio::NeXML::States.new 'sss1'
576
+
577
+ pss1 = Bio::NeXML::State.new 'ss4', :symbol => '4'
578
+ pss1.ambiguity = :polymorphic
579
+ pss1.add_member( ss1 )
580
+ pss1.add_member( ss2 )
581
+
582
+ uss1 = Bio::NeXML::State.new 'ss5', :symbol => '5'
583
+ uss1.ambiguity = :uncertain
584
+ uss1.add_member( ss1 )
585
+ uss1.add_member( ss2 )
586
+
587
+ sss1.add_state( ss1 )
588
+ sss1.add_state( ss2 )
589
+ sss1.add_state( uss1 )
590
+ sss1.add_state( pss1 )
591
+
592
+ sc1 = Bio::NeXML::Char.new 'sc1', :states => sss1
593
+ sc2 = Bio::NeXML::Char.new 'sc2', :states => sss1
594
+
595
+ sf1 = Bio::NeXML::Format.new
596
+ sf1.add_states( sss1 )
597
+ sf1.add_char( sc1 )
598
+ sf1.add_char( sc2 )
599
+
600
+ o1 = Bio::NeXML::Otu.new 'o1'
601
+ o2 = Bio::NeXML::Otu.new 'o2'
602
+
603
+ sseq1 = Bio::NeXML::Sequence.new
604
+ sseq1.value = "1 2"
605
+
606
+ sseq2 = Bio::NeXML::Sequence.new
607
+ sseq2.value = "2 2"
608
+
609
+ sr1 = Bio::NeXML::SeqRow.new 'sr1', :otu => o1
610
+ sr2 = Bio::NeXML::SeqRow.new 'sr2', :otu => o2
611
+
612
+ sr1.add_sequence( sseq1 )
613
+ sr2.add_sequence( sseq2 )
614
+
615
+ m = Bio::NeXML::Matrix.new
616
+ m.add_row( sr1 )
617
+ m.add_row( sr2 )
618
+
619
+ taxa1 = Bio::NeXML::Otus.new 'taxa1'
620
+
621
+ c1 = Bio::NeXML::StandardSeqs.new 'standardchars6', :otus => taxa1, :label => 'Standard sequences'
622
+ c1.format = sf1
623
+ c1.matrix = m
624
+
625
+ output = c1.to_xml
626
+ parsed = element( 'characters' ).first
627
+ assert match?( parsed, output )
628
+ end
629
+
630
+ end # end class TestWriter
631
+
632
+ end # end module NeXML
633
+ end # end module Bio