Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vicpaton committed Sep 12, 2024
1 parent af46d95 commit c42dcca
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 10 deletions.
101 changes: 101 additions & 0 deletions tests/test_eval_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,107 @@ def test_get_recovered_offtargets(network):
assert result['perc_offtargets'][0] == 2 / 3 * 100



@patch('networkcommons.data.omics.panacea_experiments')
@patch('networkcommons.data.omics.panacea_gold_standard')
@patch('networkcommons.data.network.get_omnipath')
@patch('networkcommons.utils.network_from_df')
@patch('networkcommons.data.omics.panacea_tables')
@patch('networkcommons.methods.run_shortest_paths')
@patch('networkcommons.methods.run_sign_consistency')
@patch('networkcommons.methods.run_all_paths')
@patch('networkcommons.methods.add_pagerank_scores')
@patch('networkcommons.methods.run_corneto_carnival')
@patch('networkcommons.eval._metrics.get_metric_from_networks')
@patch('networkcommons.eval._metrics._log')
def test_get_offtarget_panacea_evaluation(
mock_log,
mock_get_metric_from_networks,
mock_run_corneto_carnival,
mock_add_pagerank_scores,
mock_run_all_paths,
mock_run_sign_consistency,
mock_run_shortest_paths,
mock_panacea_tables,
mock_network_from_df,
mock_get_omnipath,
mock_panacea_gold_standard,
mock_panacea_experiments
):
# Mocks
mock_panacea_experiments.return_value = pd.DataFrame({
'group': ['CellA_DrugA', 'CellA_DrugB'],
'tf_scores': [True, True]
})

mock_panacea_gold_standard.return_value = pd.DataFrame({
'cmpd': ['DrugA', 'DrugA', 'DrugA'],
'target': ['TargetA', 'TargetB', 'TargetC'],
'rank': [1, 2, 3]
})

mock_network_df = pd.DataFrame({
'source': ['TargetA', 'Node1', 'TargetC', 'TargetD'],
'target': ['Node1', 'TargetC', 'TargetC', 'Node2'],
'interaction': [1, 1, 1, 1]
})
mock_network_df = mock_network_df.astype({'source': str, 'target': str})
mock_graph = nx.from_pandas_edgelist(mock_network_df, source='source', target='target', create_using=nx.DiGraph)
mock_network_from_df.return_value = mock_graph

mock_panacea_tables.side_effect = lambda **kwargs: pd.DataFrame({
'items': ['Node1', 'Node2'],
'act': [0.5, -0.3]
})

mock_run_shortest_paths.return_value = (MagicMock(), [])
mock_run_sign_consistency.return_value = (MagicMock(), [])
mock_run_all_paths.return_value = (MagicMock(), [])
mock_add_pagerank_scores.return_value = MagicMock()
mock_run_corneto_carnival.return_value = MagicMock()

mock_get_metric_from_networks.return_value = pd.DataFrame({
'perc_offtargets': [10, 25],
'network': ['shortest_path', 'all_paths']
})

# Test
_metrics.get_offtarget_panacea_evaluation(cell='CellY') # No info
mock_log.assert_called_with("EVAL: no cell-drug combinations found with TF activity scores. Exiting...")

result_df = _metrics.get_offtarget_panacea_evaluation(cell='CellA') # Only cell

# Assertins
assert isinstance(result_df, pd.DataFrame)
assert 'perc_offtargets' in result_df.columns
assert len(result_df) > 0

result_df = _metrics.get_offtarget_panacea_evaluation(cell='CellA', drug='DrugA') # both

assert isinstance(result_df, pd.DataFrame)
assert 'perc_offtargets' in result_df.columns
assert len(result_df) > 0

result_df = _metrics.get_offtarget_panacea_evaluation() # None

assert isinstance(result_df, pd.DataFrame)
assert 'perc_offtargets' in result_df.columns
assert len(result_df) > 0

mock_panacea_experiments.assert_called()
mock_panacea_gold_standard.assert_called()
mock_get_omnipath.assert_called()
mock_network_from_df.assert_called()
mock_panacea_tables.assert_called()
mock_run_shortest_paths.assert_called()
mock_run_sign_consistency.assert_called()
mock_run_all_paths.assert_called()
mock_add_pagerank_scores.assert_called()
mock_run_corneto_carnival.assert_called()
mock_get_metric_from_networks.assert_called()
mock_log.assert_called_with("EVAL: finished offtarget recovery evaluation using PANACEA TF activity scores.")


def test_all_nodes_in_ec50_dict():
network = nx.Graph([(1, 2), (2, 3)])
ec50_dict = {1: 5.0, 2: 10.0, 3: 15.0}
Expand Down
14 changes: 13 additions & 1 deletion tests/test_methods_causal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from unittest.mock import patch, MagicMock
import io
import sys
import pytest

@patch('networkcommons.methods._causal._log') # Mock the _log function
def test_run_corneto_carnival(mock_log):
Expand Down Expand Up @@ -92,4 +93,15 @@ def test_run_corneto_carnival(mock_log):
assert any("CVXPY" in line for line in lines_in_output)
assert any("Solver terminated with message: Optimization terminated successfully. (HiGHS Status 7: Optimal)" in line for line in lines_in_output)
# Check that stdout has printed lines when verbose=True
assert len(captured_verbose_output) > 0
assert len(captured_verbose_output) > 0

# TODO: why does corneto raise a TypeError? Thought it was the empty network, but it's not
# with pytest.raises(TypeError):
# _causal.run_corneto_carnival(
# nx.DiGraph(), # Empty network
# source_dict,
# target_dict,
# betaWeight=0.1,
# solver='scipy',
# verbose=True
# )
11 changes: 10 additions & 1 deletion tests/test_methods_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,19 @@ def test_run_all_paths_exceptions():
assert list(subnetwork.edges) == []


def test_add_pagerank_scores(net2):
@patch('networkcommons.methods._graph._log')
def test_add_pagerank_scores(mock_log, net2):

network, source_dict, target_dict = net2

network_with_pagerank = _graph.add_pagerank_scores(
nx.DiGraph(), # empty
source_dict,
target_dict,
personalize_for='source',
)
mock_log.assert_any_call('PPR: WARNING: Empty network, no scores added.')

network_with_pagerank = _graph.add_pagerank_scores(
network,
source_dict,
Expand Down
44 changes: 36 additions & 8 deletions tests/test_omics.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,25 +334,52 @@ def test_decryptm_experiment_no_dataset(mock_decryptm_datasets):

# FILE: omics/_panacea.py

@patch('networkcommons.data.omics._panacea._common._baseurl', return_value='http://example.com')
@patch('pandas.read_pickle')
@patch('urllib.request.urlopen')
@patch('pandas.read_csv')
@patch('os.path.exists', return_value=False)
@patch('os.makedirs')
@patch('pandas.DataFrame.to_pickle')
@patch('urllib.request.urlopen')
def test_panacea_experiments(mock_urlopen, mock_to_pickle, mock_makedirs, mock_path_exists, mock_read_pickle, mock_baseurl):
# Mock the HTTP response for the metadata file
def test_panacea_experiments(mock_to_pickle, mock_path_exists, mock_read_csv, mock_urlopen):
# Mock the metadata file (panacea__metadata.tsv)
mock_metadata = pd.DataFrame({
'group': ['ASPC_AEE788', 'ASPC_AFATINIB', 'DU145_CRIZOTINIB', 'ASPC_CEDIRANIB'],
'sample_ID': ['ID1', 'ID2', 'ID3', 'ID4']
})
mock_read_csv.return_value = mock_metadata

# Mock the HTML content returned by the remote server,
# with some lines containing the "__TF_scores.tsv" pattern
mock_html_content = """
<html>
<body>
<a href="ASPC_AEE788__TF_scores.tsv">ASPC_AEE788__TF_scores.tsv</a><br>
<a href="ASPC_AFATINIB__TF_scores.tsv">ASPC_AFATINIB__TF_scores.tsv</a><br>
<a href="DU145_CRIZOTINIB__TF_scores.tsv">DU145_CRIZOTINIB__TF_scores.tsv</a><br>
</body>
</html>
"""

# Mock the HTTP response for the TF scores directory
mock_response = MagicMock()
mock_response.read.return_value = b"group\tsample_ID\nA_B\tID1\nC_D\tID2"
mock_response.__enter__.return_value = mock_response
mock_response.read.return_value = mock_html_content.encode('utf-8')
mock_urlopen.return_value = mock_response

# Call the function under test
result_df = omics.panacea_experiments(update=True)

# Check that the result is a DataFrame
assert isinstance(result_df, pd.DataFrame)

# Check that the expected columns are in the DataFrame
assert 'group' in result_df.columns
assert 'cell' in result_df.columns
assert 'drug' in result_df.columns
assert 'tf_scores' in result_df.columns

# Check that the 'tf_scores' column has the correct True/False values
expected_tf_scores = [True, True, True, False] # CEDIRANIB should not have TF scores
assert result_df['tf_scores'].tolist() == expected_tf_scores

# Verify that the function attempts to save the result as a pickle file
mock_to_pickle.assert_called_once()


Expand Down Expand Up @@ -583,6 +610,7 @@ def test_panacea_gold_standard_update(mock_urllib, mock_pandas_topickle, mock_ma
mock_log.assert_any_call('DATA: found in cache, loading...')



# FILE: omics/_scperturb.py
import pytest
from unittest.mock import patch, MagicMock
Expand Down

0 comments on commit c42dcca

Please sign in to comment.