# Copyright (C) 2011 by Brandon Invergo (b.invergo@gmail.com)
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
import unittest
import os
import sys
from Bio.Phylo.PAML import codeml, baseml, yn00
from Bio import MissingExternalDependencyError
def is_exe(filepath):
    """Test if a file is an executable."""
    return os.path.exists(filepath) and os.access(filepath, os.X_OK)
def which(program):
    """Find the path to an executable."""
    filepath, filename = os.path.split(program)
    os_path = os.environ["PATH"].split(os.pathsep)
    if sys.platform == "win32":
            #This can vary depending on the Windows language.
            prog_files = os.environ["PROGRAMFILES"]
        except KeyError:
            prog_files = r"C:\Program Files"
        #For Windows, the user is instructed to move the programs to a folder
        #and then to add the folder to the system path. Just in case they didn't
        #do that, we can check for it in Program Files.
        likely_dirs = ["",  # Current dir
                       os.path.join(prog_files, "paml41"),
                       os.path.join(prog_files, "paml43"),
                       os.path.join(prog_files, "paml44"),
                       os.path.join(prog_files, "paml45")] + sys.path
    for path in os.environ["PATH"].split(os.pathsep):
        exe_file = os.path.join(path, program)
        if is_exe(exe_file):
            return exe_file
    return None
#Find the PAML binaries
if sys.platform == "win32":
    binaries = ["codeml.exe", "baseml.exe", "yn00.exe"]
    binaries = ["codeml", "baseml", "yn00"]
for binary in binaries:
    if which(binary) is None:
        raise MissingExternalDependencyError(
            "Install PAML if you want to use the Bio.Phylo.PAML wrapper.")
class Common(unittest.TestCase):
    """Base class for PAML unit tests."""
    del_files = []
    def __del__(self):
        """Just in case tool creates some junk files, do a clean-up."""
        del_files = self.del_files
        for filename in del_files:
            if os.path.exists(filename):
class CodemlTest(Common):
    """Tests for PAML tool codeml."""
    def setUp(self):
        self.cml = codeml.Codeml()
    def testCodemlBinary(self):
        """Test that the codeml binary runs and generates correct output
        and is the correct version.
        ctl_file = os.path.join("PAML", "Control_files", "codeml", "codeml.ctl")
        self.cml.alignment = os.path.join("PAML", "Alignments", "alignment.phylip")
        self.cml.tree = os.path.join("PAML", "Trees", "species.tree")
        self.cml.out_file = os.path.join("PAML", "temp.out")
        self.cml.working_dir = os.path.join("PAML", "codeml_test")
        results = self.cml.run()
        self.assertTrue(results["version"] > "4.0")
        self.assertTrue("NSsites" in results)
        self.assertEqual(len(results["NSsites"]), 1)
        self.assertEqual(len(results["NSsites"][0]), 5)
class BasemlTest(Common):
    """Tests for PAML tool baseml."""
    def setUp(self):
        self.bml = baseml.Baseml()
    def testBasemlBinary(self):
        """Test that the baseml binary runs and generates correct output
        and is the correct version.
        ctl_file = os.path.join("PAML", "Control_files", "baseml", "baseml.ctl")
        self.bml.alignment = os.path.join("PAML", "Alignments", "alignment.phylip")
        self.bml.tree = os.path.join("PAML", "Trees", "species.tree")
        self.bml.out_file = os.path.join("PAML", "temp.out")
        self.bml.working_dir = os.path.join("PAML", "baseml_test")
        results = self.bml.run()
        self.assertTrue(results["version"] > "4.0")
        self.assertTrue("parameters" in results)
        self.assertEqual(len(results["parameters"]), 5)
class Yn00Test(Common):
    """Tests for PAML tool yn00."""
    def setUp(self):
        self.yn = yn00.Yn00()
    def testYn00Binary(self):
        """Test that the yn00 binary runs and generates correct output.
        yn00 output does not specify the version number.
        ctl_file = os.path.join("PAML", "Control_files", "yn00", "yn00.ctl")
        self.yn.alignment = os.path.join("PAML", "Alignments", "alignment.phylip")
        self.yn.out_file = os.path.join("PAML", "temp.out")
        self.yn.working_dir = os.path.join("PAML", "yn00_test")
        results = self.yn.run()
        self.assertEqual(len(results), 5)
if __name__ == "__main__":
    runner = unittest.TextTestRunner(verbosity = 2)