def test_error_on_incorrect_dimensions(): with pytest.raises(NexusFormatException): NexusReader.from_string(""" #NEXUS begin taxa; dimensions ntax=2; taxlabels A B C; end; """)
def test_error_on_duplicate_taxa(): with pytest.raises(NexusFormatException): NexusReader.from_string(""" #NEXUS begin trees; translate 0 Tom, 1 Simon, 2 Tom; tree tree = (0,1,2) end; """)
def test_BEASTAscertainmentChecker_fail_with_non_empty(): # fail with two nex = NexusReader.from_string(""" #NEXUS Begin data; charstatelabels 1 CHAR_A_ascertainement, 2 CHAR_A, 3 CHAR_B_ascertainement, 4 CHAR_B ; Dimensions ntax=3 nchar=4; Format datatype=standard symbols="01" gap=-; Matrix A 0101 B 0101 C 10?1 ; begin assumptions; charset A = 1-2; charset B = 3-4; end; """) c = BEASTAscertainmentChecker(nex) assert len(c.errors) == 1 # should ONLY be one
def test_write_produces_end(): nex = NexusReader.from_string(""" begin assumptions; A = 1; end; """) assert "end;" in nex.write()
def test_DataHandler_NoMissingInSymbols_write(): """ Regression: Test that the missing or gap symbols are NOT in the SYMBOLS format string """ nex = NexusReader.from_string(""" #NEXUS begin data; Dimensions ntax=2 nchar=2; Format datatype=standard gap=- symbols="01"; Matrix Harry 1- Simon 0? ; End; """) expected_patterns = [ r'^begin data;$', r'^\s+dimensions ntax=2 nchar=2;$', r'^\s+format datatype=standard gap=- symbols="01";$', r"^matrix$", r"^Harry\s+1-", r"^Simon\s+0\?$", r'^\s+;$', r'^end;$', ] written = nex.write() for expected in expected_patterns: assert re.search(expected, written, re.MULTILINE), \ 'Expected "%s"' % expected
def test_error_on_duplicate_block(): with warnings.catch_warnings(record=True): with pytest.raises(NexusFormatException): NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=5 nchar=1; Format datatype=standard symbols="01" gap=-; Matrix Harry 1 ; Begin data; Dimensions ntax=5 nchar=1; Format datatype=standard symbols="01" gap=-; Matrix Harry 1 """)
def test_generic_readwrite(): expected = [ "begin sets;", " A = 1;", " B = 2;", "end;", ] nex = NexusReader.from_string("\n".join(expected)) for line in nex.sets.write().split("\n"): if line: e = expected.pop(0).strip() assert line.strip() == e
def test_read_string_returns_self(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=1 nchar=1; Format datatype=standard symbols="01" gap=-; Matrix Harry 1 ; """) assert isinstance(nex, NexusReader)
def test_no_treelabel(): nex = NexusReader.from_string(""" #NEXUS begin trees; translate 0 Tom, 1 Simon, 2 Fred; tree = (0,1,2); end; """) assert len(nex.trees.trees) == 1 assert nex.trees.trees == ['tree = (0,1,2);']
def test_labelled_unrooted(): nex = NexusReader.from_string(""" #NEXUS begin trees; translate 0 Tom, 1 Simon, 2 Fred; tree unrooted [U] = (0,1,2); end; """) assert len(nex.trees.trees) == 1 assert nex.trees.trees == ['tree unrooted [U] = (0,1,2);']
def test_LabelChecker_no_error_with_no_labels(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 001 B 001 C 001 ; """) c = LabelChecker(nex) assert len(c.errors) == 0
def test_PotentiallyUnsafeTaxaLabelsChecker(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=2 nchar=1; Format datatype=standard symbols="01" gap=-; Matrix Hary 1 Harr! 1 ; """) c = PotentiallyUnsafeTaxaLabelsChecker(nex) assert len(c.errors) == 1
def test_rooted(): nex = NexusReader.from_string(""" #NEXUS begin trees; translate 0 Tom, 1 Simon, 2 Fred; tree [&] = (0,1,2); end; """) assert len(nex.trees.trees) == 1 assert nex.trees.trees == ['tree [&] = (0,1,2);'] assert nex.trees.trees[0].rooted is None # we only recognize [&R]!
def test_EmptyCharacterChecker(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 101 B 101 C 000 ; """) c = EmptyCharacterChecker(nex) assert len(c.errors) == 1
def test_detranslate_without_translators(nex): """ Test that running detranslate when there's no translate block doesn't break the trees """ nex = NexusReader.from_string(""" #NEXUS begin trees; tree = (A,(B,C)); end; """) assert nex.trees.translators == {1: 'A', 2: 'B', 3: 'C'} assert nex.trees._been_detranslated nex.trees.detranslate() assert nex.trees.trees[0] == 'tree = (A,(B,C));'
def test_ok_starting_with_one(): nex = NexusReader.from_string(""" #NEXUS begin trees; translate 1 Tom, 2 Simon, 3 Fred; tree tree = (1,2,3) end; """) assert len(nex.trees.translators) == 3 assert '1' in nex.trees.translators assert '2' in nex.trees.translators assert '3' in nex.trees.translators
def mesquite_attributes(): nex = NexusReader.from_string(""" #NEXUS Begin data; TITLE Untitled_Block_of_Taxa; LINK Taxa = Untitled_Block_of_Taxa; Dimensions ntax=2 nchar=2; Format datatype=standard gap=- symbols="01"; Matrix Harry 00 Simon 01 ; End; """) return nex
def test_UnusualStateChecker(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 111 B 000 C 00A ; """) UnusualStateChecker.THRESHOLD = 0.3 c = UnusualStateChecker(nex) assert len(c.errors) == 1
def test_ok_starting_with_zero(): nex = NexusReader.from_string(""" #NEXUS begin trees; translate 0 Tom, 1 Simon, 2 Fred; tree tree = (0,1,2) end; """) assert len(nex.trees.translators) == 3 assert '0' in nex.trees.translators assert '1' in nex.trees.translators assert '2' in nex.trees.translators
def test_annotation_read(): nex = NexusReader.from_string(""" #NEXUS BEGIN TAXA; DIMENSIONS NTAX=3; TAXLABELS A[&!color=#aaaaaa] B[&!color=#bbbbbb] C[&!color=#cccccc] END; """) nex.taxa.annotations['A'] = '[&!color=#aaaaaa]' nex.taxa.annotations['B'] = '[&!color=#bbbbbb]' nex.taxa.annotations['C'] = '[&!color=#cccccc]' out = nex.taxa.write() assert 'A[&!color=#aaaaaa]' in out assert 'B[&!color=#bbbbbb]' in out assert 'C[&!color=#cccccc]' in out
def test_LowStateCountChecker(): nex = NexusReader.from_string(""" #NEXUS Begin data; Dimensions ntax=7 nchar=50; Format datatype=standard symbols="01" gap=-; Matrix A 11111111111111111111111111111111111111111111111111 B 11111111111111111111111111111111111111111111111111 C 11111111111111111111111111111111111111111111111111 D 11111111111111111111111111111111111111111111111111 E 11111111111111111111111111111111111111111111111111 F 11111111111111111111111111111111111111111111111111 G 00000000000000000000000000000000000000000000000001 ; """) LowStateCountChecker.THRESHOLD = 1 c = LowStateCountChecker(nex) assert len(c.errors) == 1
def test_DuplicateLabelChecker(): nex = NexusReader.from_string(""" #NEXUS Begin data; charstatelabels 1 CHAR, 2 CHAR_A, 3 CHAR ; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 001 B 001 C 001 ; """) c = DuplicateLabelChecker(nex) assert len(c.errors) == 1
def test_EmptyCharacterChecker_ignore_ascert(): nex = NexusReader.from_string(""" #NEXUS Begin data; charstatelabels 1 CHAR_ascertainement, 2 CHAR_A, 3 CHAR_B ; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 001 B 001 C 001 ; """) c = EmptyCharacterChecker(nex) assert len(c.errors) == 1 # and not two! assert len(c.messages) == 1
def test_BEASTAscertainmentCheckersingle_ascertainment_ok(): # All ok with one labelled ascertainment character nex = NexusReader.from_string(""" #NEXUS Begin data; charstatelabels 1 CHAR_ascertainement, 2 CHAR_A, 3 CHAR_B ; Dimensions ntax=3 nchar=3; Format datatype=standard symbols="01" gap=-; Matrix A 011 B 011 C 001 ; """) c = BEASTAscertainmentChecker(nex) assert len(c.errors) == 0
def test_BEASTAscertainmentCheckerfail_with_no_assumptions_block(): nex = NexusReader.from_string(""" #NEXUS Begin data; charstatelabels 1 CHAR_A_ascertainement, 2 CHAR_A, 3 CHAR_B_ascertainement, 4 CHAR_B ; Dimensions ntax=3 nchar=4; Format datatype=standard symbols="01" gap=-; Matrix A 0101 B 0101 C 0001 ; """) c = BEASTAscertainmentChecker(nex) assert len(c.errors) == 1
def test_DataHandler_trailing_comma(): """Trailing comma in charstatelabels creates an empty character at N+1""" with warnings.catch_warnings(record=True) as w: nex = NexusReader.from_string(""" BEGIN DATA; DIMENSIONS NTAX=3 NCHAR=1; FORMAT MISSING=? GAP=- SYMBOLS="01"; CHARSTATELABELS 1 ALL, ; MATRIX A 1 B 0 C 0 ; END; """) assert len(w) == 1, 'Expected 1 warning, got %r' % w assert issubclass(w[0].category, UserWarning) assert "empty character label" in str(w[-1].message) assert nex.data.nchar == 1 assert len(nex.data.charlabels) == 1 assert len(nex.data.characters) == 1
def test_from_string(nex_string): nex = NexusReader.from_string(nex_string) assert 'data' in nex.blocks assert 'Simon' in nex.blocks['data'].matrix assert 'taxa' in repr(nex.blocks['data'])
def test_roundtrip(examples): nex = NexusReader(examples.joinpath('example2.nex')) _ = NexusReader.from_string(nex.write())