Skip to content

Commit cff5312

Browse files
Fix bug and add tests for missing clade bug
This bug is triggered by defining a clade in a self closing "leaf" tag. The fix is to avoid universally trating leaves an non-structural but check if a leaf tag is a clade.
1 parent ef5d982 commit cff5312

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

src/Bio/Phylogeny/Internal/PhyloXml.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ toStructuralTree (Internal p@(XmlNode node) children) =
391391
-- Structural elements form the phylogeny,
392392
-- all other elements are attributes.
393393
isStructuralElement :: Tree XmlNode -> Boolean
394-
isStructuralElement (Leaf _) = false
394+
isStructuralElement (Leaf (XmlNode { name })) = name == "clade"
395395
isStructuralElement (Internal (XmlNode { name }) _) =
396396
A.elem name [ "phyloxml", "phylogeny", "clade" ]
397397

test/Bio/Phylogeny/PhyloXml.purs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Prelude
55
import Bio.Phylogeny
66
( Attribute(..)
77
, attributes
8+
, edges
89
, lookupNode
910
, parsePhyloXml
1011
, reportError
@@ -29,6 +30,58 @@ specs = do
2930
text <- readTextFile UTF8 $ testDir </> "phyloxml_example1.xml"
3031
expectFail "No trees in this PhyloXML document" $ parsePhyloXml text
3132

33+
it "Parses a single node tree" do
34+
let text = "<phyloxml><phylogeny><clade><name>A</name></clade></phylogeny></phyloxml>"
35+
let phylogeny = parsePhyloXml text
36+
37+
(A.length <<< roots <$> phylogeny)
38+
`shouldEqual`
39+
(Right 1)
40+
41+
case phylogeny of
42+
Right phylogeny' ->
43+
(nodeName <$> (A.catMaybes (lookupNode phylogeny' <$> (roots phylogeny'))))
44+
`shouldEqual`
45+
[ ("A" /\ 0.0) ]
46+
Left err -> fail $ reportError "" err
47+
48+
it "Parses a single node tree with name attribute" do
49+
let text = "<phyloxml><phylogeny><clade name=\"A\" /></phylogeny></phyloxml>"
50+
let phylogeny = parsePhyloXml text
51+
52+
(A.length <<< roots <$> phylogeny)
53+
`shouldEqual`
54+
(Right 1)
55+
56+
case phylogeny of
57+
Right phylogeny' ->
58+
(nodeName <$> (A.catMaybes (lookupNode phylogeny' <$> (roots phylogeny'))))
59+
`shouldEqual`
60+
[ ("A" /\ 0.0) ]
61+
Left err -> fail $ reportError "" err
62+
63+
it "Parses a 4 node tree with a fork" do
64+
let
65+
text =
66+
"<phyloxml><phylogeny rooted=\'true\'><clade name=\"A\"><clade><name>B</name></clade></clade></phylogeny></phyloxml>"
67+
let phylogeny = parsePhyloXml text
68+
69+
(A.length <<< roots <$> phylogeny)
70+
`shouldEqual`
71+
(Right 1)
72+
73+
case phylogeny of
74+
Right phylogeny' -> do
75+
(nodeName <$> vertices phylogeny')
76+
`shouldEqual`
77+
[ ("A" /\ 0.0)
78+
, ("B" /\ 0.0)
79+
]
80+
edges phylogeny'
81+
`shouldEqual`
82+
[ (1 /\ 2) ]
83+
Left err -> fail $ reportError "" err
84+
3285
it "Parses the PhyloXML example" do
3386
text <- readTextFile UTF8 $ testDir </> "phyloxml_example2.xml"
3487

test/js/parsing.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,39 @@ test("Throws when missing opening paren", (t) => {
7070
test("Throws when missing closing semicolon", (t) => {
7171
t.throws(() => parse("()"), { instanceOf: Error });
7272
});
73+
74+
test("Can parse phyloxml", (t) => {
75+
const text =
76+
'<phyloxml><phylogeny rooted=\'true\'><clade name="A"><clade><name>B</name><clade name="C" /><clade name="D" /></clade></clade></phylogeny></phyloxml>';
77+
const phy = parse(text);
78+
t.deepEqual(vertices(phy), [
79+
{
80+
name: "A",
81+
event: "Clade",
82+
branchLength: 0,
83+
ref: 1,
84+
attributes: new Map(),
85+
},
86+
{
87+
name: "B",
88+
event: "Clade",
89+
branchLength: 0,
90+
ref: 2,
91+
attributes: new Map(),
92+
},
93+
{
94+
name: "C",
95+
event: "Taxa",
96+
branchLength: 0,
97+
ref: 3,
98+
attributes: new Map(),
99+
},
100+
{
101+
name: "D",
102+
event: "Taxa",
103+
branchLength: 0,
104+
ref: 4,
105+
attributes: new Map(),
106+
},
107+
]);
108+
});

0 commit comments

Comments
 (0)