Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to pytest and implement code coverage. #167

Merged
merged 29 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[run]
source=OrthoEvol
source=OrthoEvol
disable_warnings = couldnt-parse
54 changes: 39 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
language: python
dist: xenial
os: linux
cache: pip
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
notifications:
email: [email protected]
# command to install dependencies
install:
- "pip install --upgrade pip setuptools wheel"
- "pip install --only-binary=numpy,scipy numpy scipy"
- "pip install matplotlib ipython jupyter sympy pytest"
- "pip install -r requirements.txt"
- "pip install ."
# command to run unittests via pytest
jobs:
include:
- python: 3.5
dist: trusty
install:
- pip install --upgrade pip setuptools wheel
- pip install --only-binary=numpy,scipy numpy scipy
- pip install matplotlib ipython jupyter sympy pytest codecov "pytest-cov<=2.6.0"
- pip install -r requirements.txt
- pip install .
- python: 3.6
dist: xenial
install:
- pip install --upgrade pip setuptools wheel
- pip install --only-binary=numpy,scipy numpy scipy
- pip install matplotlib ipython jupyter sympy pytest codecov pytest-cov
- pip install -r requirements.txt
- pip install .
- python: 3.7
dist: xenial
install:
- pip install --upgrade pip setuptools wheel
- pip install --only-binary=numpy,scipy numpy scipy
- pip install matplotlib ipython jupyter sympy pytest codecov pytest-cov
- pip install -r requirements.txt
- pip install .
- python: 3.8
dist: xenial
install:
- pip install --upgrade pip setuptools wheel
- pip install --only-binary=numpy,scipy numpy scipy
- pip install matplotlib ipython jupyter sympy pytest codecov pytest-cov
- pip install -r requirements.txt
- pip install .
# command to run unittests
script:
- pytest tests/
- pytest --cov-report=xml --cov=OrthoEvol tests/
# upload code coverage
after_success:
- codecov
8 changes: 4 additions & 4 deletions OrthoEvol/Orthologs/Align/msa.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ def guidance2(self, seqFile, msaProgram, seqType, dataset='MSA', seqFilter=None,
gene = Path(seqFile).stem
geneDir = self.raw_data / Path(gene)
self.guidancelog.info(geneDir)
if seqType is 'nuc':
if seqType == 'nuc':
g2_seqFile = str(geneDir / Path(gene + '_G2.ffn')) # Need for all iterations
rem_file = str(geneDir / Path(gene + '_G2_removed.ffn')) # Need for all iterations
g2_alnFile = str(geneDir / Path(gene + '_G2_na.aln'))
g2_seqcolFilter = str(geneDir / Path(gene + 'G2sfcf_na.aln'))
g2_colFilter = str(geneDir / Path(gene + '_G2cf_na.aln'))
g2_maskedFile = str(geneDir / Path(gene + '_G2mf_na.aln'))
elif seqType is 'aa':
elif seqType == 'aa':
g2_seqFile = str(geneDir / Path(gene + '_G2.faa')) # Need for all iterations
rem_file = str(geneDir / Path(gene + '_G2_removed.faa')) # Need for all iterations
g2_alnFile = str(geneDir / Path(gene + '_G2_aa.aln'))
Expand Down Expand Up @@ -176,9 +176,9 @@ def guidance2(self, seqFile, msaProgram, seqType, dataset='MSA', seqFilter=None,
elif set_iter >= iteration > 1:

# Depending on the filter strategy increment the seqCutoff
if seqFilter is "inclusive":
if seqFilter == "inclusive":
kwargs['seqCutoff'] -= kwargs['increment']
elif seqFilter is "exclusive":
elif seqFilter == "exclusive":
kwargs['seqCutoff'] += kwargs['increment']
# seqFile changes to g2_seqFile and the cutoffs change
G2Cmd = Guidance2Commandline(seqFile=g2_seqFile, msaProgram=msaProgram, seqType=seqType,
Expand Down
4 changes: 2 additions & 2 deletions OrthoEvol/Orthologs/GenBank/genbank.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def name_fasta_file(self, path, gene, org, feat_type,
# Create path variables. (typically raw_data/<gene>/GENBANK
feat_path = path
# Create a format-able string for file names
if feat_type_rank is "CDS":
if feat_type_rank == "CDS":
single = '%s_%s%s%s'
multi = '%s%s%s'
else:
Expand Down Expand Up @@ -406,7 +406,7 @@ def get_fasta_files(self, acc_dict, db=True):
for _, _, gbk_files in os.walk(str(self.target_gbk_files_path)):
# For each genbank record write a set of FASTA files.
for gbk_file in gbk_files:
if Path(gbk_file).suffix is '.gbk':
if Path(gbk_file).suffix == '.gbk':
record = SeqIO.read(gbk_file, 'genbank')
self.write_fasta_files(record, acc_dict)
self.genbanklog.info("FASTA files for %s created." % gbk_file)
Expand Down
6 changes: 3 additions & 3 deletions OrthoEvol/Tools/logit/logit.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ def custom(cls, logname, logfile, level, fmt='default'):
:return: A custom_log object is returned.
"""

if fmt is 'default':
if fmt == 'default':
fmt = '[%(levelname)-2s - %(name)s]: %(message)s'
elif fmt is 'custom':
elif fmt == 'custom':
# TODO Allow customization
raise NotImplementedError('Feature not integrated yet!')
elif fmt is not 'default' or 'custom':
elif fmt != 'default' or 'custom':
raise Exception('User did not provide a format for the logger.')

custom_log = setup_logger(name=logname, logfile=logfile,
Expand Down
2 changes: 1 addition & 1 deletion OrthoEvol/Tools/slackify/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self, slackconfig='slackconfig.cfg', cfg=True):
# Use False if you did not create a config file
if not cfg:
apikey = input('Insert your slack apikey here: ')
if len(apikey) is not 42: # Standard length of slack apikey
if len(apikey) != 42: # Standard length of slack apikey
raise ValueError('Your slack APIKEY is incorrect.')

slack = Slacker(apikey)
Expand Down
29 changes: 15 additions & 14 deletions OrthoEvol/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# Set up logging
blastutils_log = LogIt().default(logname="blast-utils", logfile=None)
seqidlist_log = LogIt().default(logname="gi-lists", logfile=None)
utils_log = LogIt().default(logname="utils", logfile=None)
_datefmt = '%I:%M:%S %p on %m-%d-%Y'
_date = str(datetime.now().strftime(_datefmt))

Expand Down Expand Up @@ -445,17 +446,17 @@ def multi_fasta_manipulator(self, target_file, man_file, output_file,
# Create a new multi-fasta record object using the target_file,
# reference, and output
# Remove specific sequences from a fasta file
if manipulation is 'remove':
if manipulation == 'remove':
self.multi_fasta_remove(target_file, man_file, new_file)
# Combine all the FASTA sequence in one record object
elif manipulation is 'add':
elif manipulation == 'add':
self.muli_fasta_add(target_file, man_file, new_file)
# Sort one fasta file based on the order of another
# Works for alignments
elif manipulation is 'sort':
elif manipulation == 'sort':
self.multi_fasta_sort(target_file, man_file, new_file)

print('A new fasta file has been created.')
utils_log.info('A new fasta file has been created.')
return new_file

# def dir_config(path, tier_frame_dict):
Expand Down Expand Up @@ -505,7 +506,7 @@ def multi_fasta_remove(self, target_file, man_file, output_file):
target_file,
'fasta') if record.id in ids)

print('Sequences have been filtered.')
utils_log.info('Sequences have been filtered.')
SeqIO.write(new_records, str(output_file), 'fasta')
SeqIO.write(old_records, str(rem_file), 'fasta')

Expand All @@ -532,11 +533,11 @@ def muli_fasta_add(self, target_file, man_file, output_file):
target_file, 'fasta', ), SeqIO.parse(man_file, 'fasta'))
count = SeqIO.write(new_records, tmp_file, 'fasta')
tmp_file.seek(0)
print('temp file count: ' + str(count))
utils_log.info('temp file count: ' + str(count))
SeqIO.write(SeqIO.parse(tmp_file, 'fasta'), str(output_file), 'fasta')
print('Sequences have been added.')
utils_log.info('Sequences have been added.')
else:
print('You can only add files together. Not python objects.')
utils_log.warning('You can only add files together. Not python objects.')

def multi_fasta_sort(self, target_file, man_file, output_file):
"""Sorts selected reference sequences in a multi-FASTA files.
Expand Down Expand Up @@ -569,15 +570,15 @@ def multi_fasta_sort(self, target_file, man_file, output_file):
for unsorted_aln_record in SeqIO.parse(target_file, 'fasta'):
# If an appropriate id is found, then append to the MSA object.
if unsorted_aln_record.id == sorted_seq_record.id:
print(unsorted_aln_record.id)
print(sorted_seq_record.id)
utils_log.info(unsorted_aln_record.id)
utils_log.info(sorted_seq_record.id)
aln.append(unsorted_aln_record) # MSA object
break
count = AlignIO.write(aln, tmp_file, 'fasta')
tmp_file.seek(0)
print('temp file count: ' + str(count))
utils_log.info('temp file count: ' + str(count))
AlignIO.write(AlignIO.read(tmp_file, 'fasta'), str(output_file), 'fasta')
print('Alignment has been sorted.')
utils_log.info('Alignment has been sorted.')


class OrthologUtils(BlastUtils, GenbankUtils):
Expand Down Expand Up @@ -877,7 +878,7 @@ def __init__(self, packagename):
def _getversion(self):
import_module(self.packagename)
version = pkg_resources.get_distribution(self.packagename).version
print('Version %s of %s is installed.' % (version, self.packagename))
utils_log.info('Version %s of %s is installed.' % (version, self.packagename))


class FunctionRepeater(object):
Expand Down Expand Up @@ -933,7 +934,7 @@ def system_cmd(self, cmd, timeout=None, print_flag=True,
for line in iter(proc.stdout.readline, ""):
stdout_list.append(line.rstrip())
if print_flag:
print(line, end="")
utils_log.info(line, end="")
sys.stdout.flush()
if write_flag:
with open(file_name, 'a') as output_file:
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
addopts = -ra -q
testpaths =
tests
Empty file added tests/__init__.py
Empty file.